From 653b6bea97a8d14808ff699a8c6ff42c38dc18eb Mon Sep 17 00:00:00 2001 From: s1lentq Date: Wed, 6 May 2015 14:17:22 +0600 Subject: [PATCH] initial commit --- Makefile | 70 ++ README.md | 7 +- bin/2.0/localizebugfix.dll | Bin 0 -> 62976 bytes bin/2.0/localizebugfix.pdb | Bin 0 -> 1002496 bytes bin/2.0/localizebugfix_mm_i386.so | Bin 0 -> 19172 bytes bin/2.3/localizebugfix.dll | Bin 0 -> 51712 bytes bin/2.3/localizebugfix.pdb | Bin 0 -> 846848 bytes bin/2.3/localizebugfix_2_3.7z | Bin 0 -> 28950 bytes bin/2.3/localizebugfix_mm_i386.so | Bin 0 -> 23268 bytes include/CVector.h | 502 ++++++++++++ include/main.h | 128 +++ include/memory.h | 85 ++ main.cpp | 251 ++++++ memory.cpp | 194 +++++ meta_api.cpp | 154 ++++ msvc10/localizebugfix.sln | 20 + msvc10/localizebugfix.suo | Bin 0 -> 13824 bytes msvc10/localizebugfix.vcxproj | 142 ++++ msvc10/localizebugfix.vcxproj.filters | 39 + sdk/hlsdk/common/beamdef.h | 64 ++ sdk/hlsdk/common/cl_entity.h | 117 +++ sdk/hlsdk/common/com_model.h | 353 ++++++++ sdk/hlsdk/common/con_nprint.h | 33 + sdk/hlsdk/common/const.h | 776 ++++++++++++++++++ sdk/hlsdk/common/crc.h | 54 ++ sdk/hlsdk/common/cvardef.h | 36 + sdk/hlsdk/common/demo_api.h | 33 + sdk/hlsdk/common/director_cmds.h | 38 + sdk/hlsdk/common/dlight.h | 35 + sdk/hlsdk/common/dll_state.h | 23 + sdk/hlsdk/common/engine_launcher_api.h | 112 +++ sdk/hlsdk/common/entity_state.h | 195 +++++ sdk/hlsdk/common/entity_types.h | 26 + sdk/hlsdk/common/event_api.h | 53 ++ sdk/hlsdk/common/event_args.h | 52 ++ sdk/hlsdk/common/event_flags.h | 49 ++ sdk/hlsdk/common/exefuncs.h | 50 ++ sdk/hlsdk/common/hltv.h | 57 ++ sdk/hlsdk/common/in_buttons.h | 40 + sdk/hlsdk/common/interface.h | 129 +++ sdk/hlsdk/common/ivoicetweak.h | 37 + sdk/hlsdk/common/mathlib.h | 156 ++++ sdk/hlsdk/common/net_api.h | 101 +++ sdk/hlsdk/common/netadr.h | 42 + sdk/hlsdk/common/nowin.h | 15 + sdk/hlsdk/common/particledef.h | 59 ++ sdk/hlsdk/common/pmtrace.h | 45 ++ sdk/hlsdk/common/qfont.h | 42 + sdk/hlsdk/common/r_efx.h | 199 +++++ sdk/hlsdk/common/r_studioint.h | 149 ++++ sdk/hlsdk/common/ref_params.h | 75 ++ sdk/hlsdk/common/screenfade.h | 26 + sdk/hlsdk/common/studio_event.h | 31 + sdk/hlsdk/common/triangleapi.h | 61 ++ sdk/hlsdk/common/usercmd.h | 43 + sdk/hlsdk/common/weaponinfo.h | 54 ++ sdk/hlsdk/dlls/activity.h | 109 +++ sdk/hlsdk/dlls/activitymap.h | 97 +++ sdk/hlsdk/dlls/animation.h | 47 ++ sdk/hlsdk/dlls/basemonster.h | 94 +++ sdk/hlsdk/dlls/cbase.h | 797 +++++++++++++++++++ sdk/hlsdk/dlls/cdll_dll.h | 45 ++ sdk/hlsdk/dlls/client.h | 65 ++ sdk/hlsdk/dlls/decals.h | 75 ++ sdk/hlsdk/dlls/doors.h | 33 + sdk/hlsdk/dlls/effects.h | 209 +++++ sdk/hlsdk/dlls/enginecallback.h | 162 ++++ sdk/hlsdk/dlls/explode.h | 32 + sdk/hlsdk/dlls/extdll.h | 88 ++ sdk/hlsdk/dlls/func_break.h | 74 ++ sdk/hlsdk/dlls/game.h | 45 ++ sdk/hlsdk/dlls/gamerules.h | 360 +++++++++ sdk/hlsdk/dlls/hornet.h | 58 ++ sdk/hlsdk/dlls/items.h | 29 + sdk/hlsdk/dlls/maprules.h | 22 + sdk/hlsdk/dlls/monsterevent.h | 34 + sdk/hlsdk/dlls/monsters.h | 88 ++ sdk/hlsdk/dlls/nodes.h | 54 ++ sdk/hlsdk/dlls/plane.h | 43 + sdk/hlsdk/dlls/player.h | 324 ++++++++ sdk/hlsdk/dlls/saverestore.h | 176 ++++ sdk/hlsdk/dlls/schedule.h | 31 + sdk/hlsdk/dlls/scriptevent.h | 29 + sdk/hlsdk/dlls/skill.h | 147 ++++ sdk/hlsdk/dlls/soundent.h | 95 +++ sdk/hlsdk/dlls/spectator.h | 27 + sdk/hlsdk/dlls/talkmonster.h | 26 + sdk/hlsdk/dlls/teamplay_gamerules.h | 57 ++ sdk/hlsdk/dlls/trains.h | 127 +++ sdk/hlsdk/dlls/util.h | 541 +++++++++++++ sdk/hlsdk/dlls/vector.h | 112 +++ sdk/hlsdk/dlls/weapons.h | 1015 ++++++++++++++++++++++++ sdk/hlsdk/engine/Sequence.h | 201 +++++ sdk/hlsdk/engine/anorms.h | 177 +++++ sdk/hlsdk/engine/archtypes.h | 41 + sdk/hlsdk/engine/cdll_int.h | 311 ++++++++ sdk/hlsdk/engine/custom.h | 103 +++ sdk/hlsdk/engine/customentity.h | 38 + sdk/hlsdk/engine/edict.h | 38 + sdk/hlsdk/engine/eiface.h | 528 ++++++++++++ sdk/hlsdk/engine/keydefs.h | 131 +++ sdk/hlsdk/engine/progdefs.h | 226 ++++++ sdk/hlsdk/engine/progs.h | 82 ++ sdk/hlsdk/engine/shake.h | 55 ++ sdk/hlsdk/engine/studio.h | 362 +++++++++ sdk/hlsdk/pm_shared/pm_debug.h | 28 + sdk/hlsdk/pm_shared/pm_defs.h | 226 ++++++ sdk/hlsdk/pm_shared/pm_info.h | 26 + sdk/hlsdk/pm_shared/pm_materials.h | 37 + sdk/hlsdk/pm_shared/pm_movevars.h | 47 ++ sdk/hlsdk/pm_shared/pm_shared.h | 40 + sdk/metamod/api_info.h | 296 +++++++ sdk/metamod/commands_meta.h | 81 ++ sdk/metamod/conf_meta.h | 96 +++ sdk/metamod/dllapi.h | 192 +++++ sdk/metamod/engine_api.h | 464 +++++++++++ sdk/metamod/engine_t.h | 81 ++ sdk/metamod/enginecallbacks.h | 78 ++ sdk/metamod/engineinfo.h | 255 ++++++ sdk/metamod/game_support.h | 55 ++ sdk/metamod/games.h | 130 +++ sdk/metamod/h_export.h | 49 ++ sdk/metamod/info_name.h | 56 ++ sdk/metamod/linkent.h | 117 +++ sdk/metamod/log_meta.h | 102 +++ sdk/metamod/meta_api.h | 237 ++++++ sdk/metamod/meta_eiface.h | 478 +++++++++++ sdk/metamod/metamod.h | 426 ++++++++++ sdk/metamod/mhook.h | 160 ++++ sdk/metamod/mlist.h | 90 +++ sdk/metamod/mplayer.h | 91 +++ sdk/metamod/mplugin.h | 422 ++++++++++ sdk/metamod/mqueue.h | 68 ++ sdk/metamod/mreg.h | 186 +++++ sdk/metamod/mutil.h | 160 ++++ sdk/metamod/osdep.h | 522 ++++++++++++ sdk/metamod/plinfo.h | 82 ++ sdk/metamod/reg_support.h | 48 ++ sdk/metamod/sdk_util.h | 115 +++ sdk/metamod/studioapi.h | 56 ++ sdk/metamod/support_meta.h | 148 ++++ sdk/metamod/thread_logparse.h | 59 ++ sdk/metamod/tqueue.h | 144 ++++ sdk/metamod/types_meta.h | 82 ++ sdk/metamod/vdate.h | 44 + sdk/metamod/vers_meta.h | 55 ++ 146 files changed, 18837 insertions(+), 4 deletions(-) create mode 100644 Makefile create mode 100644 bin/2.0/localizebugfix.dll create mode 100644 bin/2.0/localizebugfix.pdb create mode 100644 bin/2.0/localizebugfix_mm_i386.so create mode 100644 bin/2.3/localizebugfix.dll create mode 100644 bin/2.3/localizebugfix.pdb create mode 100644 bin/2.3/localizebugfix_2_3.7z create mode 100644 bin/2.3/localizebugfix_mm_i386.so create mode 100644 include/CVector.h create mode 100644 include/main.h create mode 100644 include/memory.h create mode 100644 main.cpp create mode 100644 memory.cpp create mode 100644 meta_api.cpp create mode 100644 msvc10/localizebugfix.sln create mode 100644 msvc10/localizebugfix.suo create mode 100644 msvc10/localizebugfix.vcxproj create mode 100644 msvc10/localizebugfix.vcxproj.filters create mode 100644 sdk/hlsdk/common/beamdef.h create mode 100644 sdk/hlsdk/common/cl_entity.h create mode 100644 sdk/hlsdk/common/com_model.h create mode 100644 sdk/hlsdk/common/con_nprint.h create mode 100644 sdk/hlsdk/common/const.h create mode 100644 sdk/hlsdk/common/crc.h create mode 100644 sdk/hlsdk/common/cvardef.h create mode 100644 sdk/hlsdk/common/demo_api.h create mode 100644 sdk/hlsdk/common/director_cmds.h create mode 100644 sdk/hlsdk/common/dlight.h create mode 100644 sdk/hlsdk/common/dll_state.h create mode 100644 sdk/hlsdk/common/engine_launcher_api.h create mode 100644 sdk/hlsdk/common/entity_state.h create mode 100644 sdk/hlsdk/common/entity_types.h create mode 100644 sdk/hlsdk/common/event_api.h create mode 100644 sdk/hlsdk/common/event_args.h create mode 100644 sdk/hlsdk/common/event_flags.h create mode 100644 sdk/hlsdk/common/exefuncs.h create mode 100644 sdk/hlsdk/common/hltv.h create mode 100644 sdk/hlsdk/common/in_buttons.h create mode 100644 sdk/hlsdk/common/interface.h create mode 100644 sdk/hlsdk/common/ivoicetweak.h create mode 100644 sdk/hlsdk/common/mathlib.h create mode 100644 sdk/hlsdk/common/net_api.h create mode 100644 sdk/hlsdk/common/netadr.h create mode 100644 sdk/hlsdk/common/nowin.h create mode 100644 sdk/hlsdk/common/particledef.h create mode 100644 sdk/hlsdk/common/pmtrace.h create mode 100644 sdk/hlsdk/common/qfont.h create mode 100644 sdk/hlsdk/common/r_efx.h create mode 100644 sdk/hlsdk/common/r_studioint.h create mode 100644 sdk/hlsdk/common/ref_params.h create mode 100644 sdk/hlsdk/common/screenfade.h create mode 100644 sdk/hlsdk/common/studio_event.h create mode 100644 sdk/hlsdk/common/triangleapi.h create mode 100644 sdk/hlsdk/common/usercmd.h create mode 100644 sdk/hlsdk/common/weaponinfo.h create mode 100644 sdk/hlsdk/dlls/activity.h create mode 100644 sdk/hlsdk/dlls/activitymap.h create mode 100644 sdk/hlsdk/dlls/animation.h create mode 100644 sdk/hlsdk/dlls/basemonster.h create mode 100644 sdk/hlsdk/dlls/cbase.h create mode 100644 sdk/hlsdk/dlls/cdll_dll.h create mode 100644 sdk/hlsdk/dlls/client.h create mode 100644 sdk/hlsdk/dlls/decals.h create mode 100644 sdk/hlsdk/dlls/doors.h create mode 100644 sdk/hlsdk/dlls/effects.h create mode 100644 sdk/hlsdk/dlls/enginecallback.h create mode 100644 sdk/hlsdk/dlls/explode.h create mode 100644 sdk/hlsdk/dlls/extdll.h create mode 100644 sdk/hlsdk/dlls/func_break.h create mode 100644 sdk/hlsdk/dlls/game.h create mode 100644 sdk/hlsdk/dlls/gamerules.h create mode 100644 sdk/hlsdk/dlls/hornet.h create mode 100644 sdk/hlsdk/dlls/items.h create mode 100644 sdk/hlsdk/dlls/maprules.h create mode 100644 sdk/hlsdk/dlls/monsterevent.h create mode 100644 sdk/hlsdk/dlls/monsters.h create mode 100644 sdk/hlsdk/dlls/nodes.h create mode 100644 sdk/hlsdk/dlls/plane.h create mode 100644 sdk/hlsdk/dlls/player.h create mode 100644 sdk/hlsdk/dlls/saverestore.h create mode 100644 sdk/hlsdk/dlls/schedule.h create mode 100644 sdk/hlsdk/dlls/scriptevent.h create mode 100644 sdk/hlsdk/dlls/skill.h create mode 100644 sdk/hlsdk/dlls/soundent.h create mode 100644 sdk/hlsdk/dlls/spectator.h create mode 100644 sdk/hlsdk/dlls/talkmonster.h create mode 100644 sdk/hlsdk/dlls/teamplay_gamerules.h create mode 100644 sdk/hlsdk/dlls/trains.h create mode 100644 sdk/hlsdk/dlls/util.h create mode 100644 sdk/hlsdk/dlls/vector.h create mode 100644 sdk/hlsdk/dlls/weapons.h create mode 100644 sdk/hlsdk/engine/Sequence.h create mode 100644 sdk/hlsdk/engine/anorms.h create mode 100644 sdk/hlsdk/engine/archtypes.h create mode 100644 sdk/hlsdk/engine/cdll_int.h create mode 100644 sdk/hlsdk/engine/custom.h create mode 100644 sdk/hlsdk/engine/customentity.h create mode 100644 sdk/hlsdk/engine/edict.h create mode 100644 sdk/hlsdk/engine/eiface.h create mode 100644 sdk/hlsdk/engine/keydefs.h create mode 100644 sdk/hlsdk/engine/progdefs.h create mode 100644 sdk/hlsdk/engine/progs.h create mode 100644 sdk/hlsdk/engine/shake.h create mode 100644 sdk/hlsdk/engine/studio.h create mode 100644 sdk/hlsdk/pm_shared/pm_debug.h create mode 100644 sdk/hlsdk/pm_shared/pm_defs.h create mode 100644 sdk/hlsdk/pm_shared/pm_info.h create mode 100644 sdk/hlsdk/pm_shared/pm_materials.h create mode 100644 sdk/hlsdk/pm_shared/pm_movevars.h create mode 100644 sdk/hlsdk/pm_shared/pm_shared.h create mode 100644 sdk/metamod/api_info.h create mode 100644 sdk/metamod/commands_meta.h create mode 100644 sdk/metamod/conf_meta.h create mode 100644 sdk/metamod/dllapi.h create mode 100644 sdk/metamod/engine_api.h create mode 100644 sdk/metamod/engine_t.h create mode 100644 sdk/metamod/enginecallbacks.h create mode 100644 sdk/metamod/engineinfo.h create mode 100644 sdk/metamod/game_support.h create mode 100644 sdk/metamod/games.h create mode 100644 sdk/metamod/h_export.h create mode 100644 sdk/metamod/info_name.h create mode 100644 sdk/metamod/linkent.h create mode 100644 sdk/metamod/log_meta.h create mode 100644 sdk/metamod/meta_api.h create mode 100644 sdk/metamod/meta_eiface.h create mode 100644 sdk/metamod/metamod.h create mode 100644 sdk/metamod/mhook.h create mode 100644 sdk/metamod/mlist.h create mode 100644 sdk/metamod/mplayer.h create mode 100644 sdk/metamod/mplugin.h create mode 100644 sdk/metamod/mqueue.h create mode 100644 sdk/metamod/mreg.h create mode 100644 sdk/metamod/mutil.h create mode 100644 sdk/metamod/osdep.h create mode 100644 sdk/metamod/plinfo.h create mode 100644 sdk/metamod/reg_support.h create mode 100644 sdk/metamod/sdk_util.h create mode 100644 sdk/metamod/studioapi.h create mode 100644 sdk/metamod/support_meta.h create mode 100644 sdk/metamod/thread_logparse.h create mode 100644 sdk/metamod/tqueue.h create mode 100644 sdk/metamod/types_meta.h create mode 100644 sdk/metamod/vdate.h create mode 100644 sdk/metamod/vers_meta.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5e0c49c --- /dev/null +++ b/Makefile @@ -0,0 +1,70 @@ +#(C)2004-2005 AMX Mod X Development Team +# Makefile written by David "BAILOPAN" Anderson + +HLSDK = sdk/hlsdk +METAMOD = sdk/metamod +M_INCLUDE = include + +OPT_FLAGS = -O2 -funroll-loops -s -pipe -fomit-frame-pointer -fno-strict-aliasing +DEBUG_FLAGS = -g -ggdb3 +CPP = g++ +NAME = localizebugfix + +BIN_SUFFIX_32 = mm_i386.so +BIN_SUFFIX_64 = mm_amd64.so + +OBJECTS = main.cpp memory.cpp meta_api.cpp + +LINK = + +INCLUDE = -I. -I$(M_INCLUDE)/ -I$(HLSDK)/common -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/pm_shared -I$(METAMOD) + +GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1) + +ifeq "$(GCC_VERSION)" "4" + OPT_FLAGS += -fvisibility=hidden -fvisibility-inlines-hidden +endif + +ifeq "$(DEBUG)" "true" + BIN_DIR = Debug + CFLAGS = $(DEBUG_FLAGS) +else + BIN_DIR = Release + CFLAGS = $(OPT_FLAGS) +endif + +CFLAGS += -DNDEBUG -Wall -Wno-char-subscripts -Wno-unknown-pragmas -Wno-write-strings -Wno-deprecated -Wno-non-virtual-dtor -fno-exceptions -DHAVE_STDINT_H -fno-rtti -static-libgcc -m32 + +ifeq "$(AMD64)" "true" + BINARY = $(NAME)_$(BIN_SUFFIX_64) + CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64 +else + BINARY = $(NAME)_$(BIN_SUFFIX_32) + CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32 + OPT_FLAGS += -march=i586 +endif + +OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) + +$(BIN_DIR)/%.o: %.cpp + $(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $< + +all: + mkdir -p $(BIN_DIR) + $(MAKE) $(NAME) + +amd64: + $(MAKE) all AMD64=true + +$(NAME): $(OBJ_LINUX) + $(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY) + +debug: + $(MAKE) all DEBUG=true + +default: all + +clean: + rm -rf $(BIN_DIR)/*.o + rm -rf $(BIN_DIR)/$(NAME)_$(BIN_SUFFIX_32) + rm -rf $(BIN_DIR)/$(NAME)_$(BIN_SUFFIX_64) diff --git a/README.md b/README.md index 07c42ee..afc2a29 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -localizebugfix -============== - -Fix localization strings in nickname and chat +#localizebugfix + +Fix localization strings in nickname and chat diff --git a/bin/2.0/localizebugfix.dll b/bin/2.0/localizebugfix.dll new file mode 100644 index 0000000000000000000000000000000000000000..505bc9f082ad458cc35e75ff7cb798c1f6fa9df3 GIT binary patch literal 62976 zcmeFa4|J5pxj+7Hb~jnVhFv7VAVF3QiUu{hLCY{`|LYG&^r(ri zjFMg+@%A-)4GZ4BW^v%b4UY9y>%LdD>LJGitJbbvCp+$6?Wj`LIv!l>n0s%r`q}__xN#*9*V%@tLqQ`k#LMAz{Dt_yfZJ`Qwv>{j7k? z=zsC?D&hZ~uope}K!Ec4N6ft*Nm^hqOTS$(adAAZQ%bmIq#;?7wje~-Lq|Jc+hMi~ zzg@T!B*`opL_pk@yzryZrfoM!36dKgB%*YKw(fO&AW6SPsHsDeCR4P-Aib<-MZTfG zY=hK2Qj)wsk)({F&~LfA-~5NZ0iO2n$}g7k7J2o`;7*> z+hy*9RW*X=fmG_6<*_1|jbdr%5gxKWs+kE+Z8g;nJap+7}2N#5{+rJqhY;)mB^p(29r?_S;C%f&h!jMvx0GImnD=^ zhphR=0Zl7oe?i4j-y$`S0wu-PxD9rjM8lgRS)s+}FVfOpG8oVd1jFt&u_e}m2bqLHe@*JzL!k zDAjp5RM^K_a|dO6V@dP!=V2_?Dul%IDwG!#+YC#_hvWyIb%r8=7hF{1%}EQeT$ zvB$5N4_Hvu7=vluI8wBqvB%ZA>7w&6YkdU+L+bs^w!NkIqmk`J{Aob5KEhs8%qwnh zE{mvnR98v9#o3%I_|L|%+gXaJe`;+g^>MH*YKE$4BZYbSH#$9rM6wkjfyhonoKxw2 zEciukQ9en8g6KGvOe)~Hzg;f!Qg>xOLBmvvFppS|gNZ^LyBqo=3ZWOL2M zo0Q~Pt|L`v1QojH0o07-(T|+XF}n1zY(IP05~xEz`S;Nzj6VGt^#Rz+f|-|C#|qY3 z*0mZTqJqq8VN%heeOCgKuhZd%q4yU5HNwEI(gT~3qspz7)_rI;iO-3_URIkJKejY( zCdTCHcLNe*c%+tQLX$O7sK3(W!-%zrChTWgs-}n3dXtCzK>-bJs5b?NcwAs+91C{$P*1mK73f8PkitQSNN;4#0i=^r8Xfng*{1w|#n%ri@fQ{ia-{zv^K07Ta#OX4^eq zi{`^M0M|ft23+63^-c74xccGhk51N0V@iKCrNNGjMq};b}YKi_$;7{zEoo&sx5>-6FpBp1dp?nJ~SQ8q>3Id^pCN|2I^4yn_UA_WS@Lwc* zuwcEC#P1yqxI~t3a+z12LgZM6M1%1b{@W3hj|rhY?)3>us#>r<0fiW%$;^VB-6o1` zEh{}}(wk8|ZPyfQxUid7fQp%?TiyE-TGFs(EM{PDzz8;_DHiU;S`%avy@J&c0bzQz z?J*ThqUf6Heo0PZg?;L(_1_$hh{}QeV5uW1si-AO*^XKOe3k$&jZ}&px1hL^63`8G z<`5R0;HJZ{7(-Z8nh1rRSoRVM_RCOEJ5B#91g^LY0RYE~4}N#?tG=sv3l)FcKPlew zzf-*BAB!Ixyl}7unHGPsuVFOXoJl0KuHgrUx*mB6>qSgzLz3ERn0`>c5^KzqhD6kBfpm8O*7cF544;Gu-S2}YqSqox9gnk(OM#efvij6 zc_y_Fx$BxjMBJ>Q< zpiueN7A?UWp1M~{vlE*Xg@YaBkx%rXlz7#X#^%CkHsk8=~-@+OXC<%67!tm zp93($Qvs=yEWz#pK=1MK&ArD<3edCGKqqA>1Jc>-?8#Luwx^n1tx6gt;#`q2f%G(t)@cc8GhDlGx;+kpF+h|^&45)4;>{ahvYv zMyDi2yZFB#UQ5d$5?l$o=h53FscA12mySGx&5tDUIx8UGOY<}3me|C#-T!}UN zLhSU3#7Ao8myxFH7-)!RB0hT9skz#eWx072zNJ=6Av;vvpPM)NJnC%bL?pS@cE!fe z-;6{PQ3ziLWa7O`3yv-lHaIl`8>Qww5ALeTW`2GoNHbcg_9ZAK{15O1Qn6h`zt6h@ z*py(*_S)*K=rx~~BhuuYM%h{#4Rfsny>O-9$4?_&Nr{%0jzA2yg(fYU?&Ck6jL@zQ zG_=}hRFeGMH3|XFW;cHu zDo>HE1+o#$dans9_{iQX#McBi8QD9U++bsV)*YZtn^OztXZXGRr^wjZY}?b$T0&b) zp)Hos7Hi9=_K_{&E%smk`q%rWbz(FhvI02ko!2R0L#m#k-UGBJZb-Et zY@yP-qD;rS_H+jJN`e(Q-@uNl*dGq^i<;)uHk!0F2YUZ?N=I$qPsG+-UuPzM=ytVL zoo@(!4bavg1voIVWQU(Ug8I&!E%lM0^%3+!|w$s?jy8=V~X-qe)uTiY`=B<|}s9V=a z@|A2;00YT_`K=qvKX6^X1i+EX6n+M+RYHRbAR*vrA40+&?)B?~g2uz0 z2ofVSJSW5Fl+N()AEr)HPDQgC@(mbdH`;d3wC!%j3f$A#P*aXb z%Ust4f87gZR1)KNNm)Bj?+AyYO6)9?ld8XsxH&j1x@Qt8eU~?6+u=Etri)56`)J z-vDx}u~^*ml?!Z+iH}ASh;QxYW>8$EU#HynInVUm&Vhb)t##jT}VNd@01Y7VcBqM}x-IR*kh$EM<$EeOj0MV-l z0fLzPu!h@B`SJIL!rS4bgw1-wxyaeg9y}YV-0ZMNmh~ z_ZWQI?q>M-kKj}f+1X>%{&_2@x5nrGoNyv^*{uXfQG5{qOG?692K#oa-nXM!60jc$ zB$B-RW&+Ax(GOY2JkwC{SPE9#L|3=@coKOp>tkzBlU>;2gDR#%+~?|*C;LOwcqI*W z%z@*5{A)PXnNkT&g6&`Eli&s-VeEFr?osU9I*9MQmJD>$F;rN$J^|;i$I5LBCg2Qi zpy2guVzY21AZZqU7dGZ^{vepQU;$bVNo>^CH9lSfE=lZWa3d+k-~mA2kA-~+m^2AO z#4a_WrA-5U3Xu#J=R0UYpEd&_tQ!T6*K#=6g}zXyoox)jO#rQBkw#j~V?4`ay;@H9 zAf(ozrif*JBjrc&qcE?{MItptl+dM40spcDx~cBXSa$?YK1szCP`-+#Er0pXe+u9V z3znkuLR(TpTh_Ne){ZWn)B4yw82WSC@&m*_z*Qck8i@@w@zdc;iJ5>$l?w;}+Z^n_ zLiua3B(XG7L&2?WT*F_*%uy0&RoFpDd?V0_pjhC6>~902CDhK7g@YE!TACMV>Khr> z#}A=LwGPo-3**}!FP1T^8$yL1dHO%w@}yTvKHf*<5Zm+6jwh5D9pU4@pxv^w2PG{) zNhB%80QT{%C`goJskHO^v2v$9a0Jbm{tlY)5d;9|V2`b?5A|UA*rmvz??SPc&!3|E z?$Uizb>D5eZ-(x>PWQQWUz+ZltNW64UxDts0C_+O%U_;H-9&|O3P5w6$bv1_gj)g_ zA6KCYg9|}T=lFj9Dgnpa+^_f2FDW6yh_ACPYmoLjKmQFDxh1YVA&E?_)x;RGs&`4W z4ZLZ1$6;`yF(06O`EG1eiJV3ERo#T32)V7iLU)VhWNhbpk6LY!lpA7n&2otFwGU9o zG4Xw>AlDCQhiEConE8&~E6wi@qZk+(FtP@v6FgGj) zR3QB+F+l{ZWH+6nVe~;j5*{)7J_z(-boiUZp7{eck02zLLnSoPpp(a{c?2lQDQX@8 zNiyatC9{#L(?l_ibKz<;Q^Nah0_}_Kw@9lG|EAbDwbiwtCG|m%IgOT_f|LIeJ4r2v zlCvBk4f{Zci6N`$`RT~&j39=rD1+ZKS81iUw zv&qIhTo>m;KD;!lgi0+f)fOE7axb|0Bn=JWtQ19uhFTK#}xhR!H zlbwg_OZ!?q7o=IpsnVdWPu13&NM2M#2Pw#>(%|KW8)&X_pgZi-Jm+b5(M`JxoZ+V0 z_IUcQ^H^)D&kGrLH_5QE=MZAq@N8{aBz87R=fTeAhPj!RVs^Zx)4~>KT6zznM=dECz;EuY(cBagG>*R_FxEv$w0I*%B;jTh9jn%b>7-*vXC z2Tiq~N(Mu%k}-)a`8~1>ilz1oWL={iDqFFPR#>z9r$^*FunRad{d4&S$acSM;dTV2 zA?PH65)t%%^rvMjbev}oAYCLp`y1WrCrfmN&+qJ^u`&a)LDpA-k#IwV)^Lz!S0DptzLkJT?7Jz^&QpXMb_j)&zH%jpS` z6FOQ`rsR68^8XOCmSLC)PLjrdia8`EZOw%fl_-q>S7IIBzk}@4mZPFE1Ol&NjO&vg zC@d}T61?CX#1r5*Bbn9_1EuP=)2vQ`X)6H%*&=`Fdg5+yut|c=VUEb`qdCIID{+$O z<5R}a_qD0?{ZH|I1~v8ZAifaW#so67ECfN?h)CI};9)sII|^C1OR-j+jyJrTx0IIQ z^0)xmd74hk{CYISL45L#!6aAX#Z6p-Ym;#W?xf;YElWBXF-BaR<`zfqWU~ zrZ$#@Y!a|yXfwG6s?Mr;%c-0dW%Bp{x%ffkN+nqogeEj>wE z6UXIIlus#UkmDj(R@xE$b(`nZRJ1{D^(i;34Wl9UW3*+VhVYy+MZakCbj}q3odq#~ z&LMzK0YGvqjXO{owHh0w8{0&!X#z!aJaQeHgQ#XdEkY45TM+sHg+}W0eAj86#^1OG$SkztJW}`XBEJWRlcow= za2%3AVj5n;L&g1UnKk6$p~BPZr2%;b^hLs^Wo*G?so}YgL0zMpLGas$agoYC$#esn#SplO7yk5Hq5U1Kk593U;Hur%I z4|OUxs(Ev10LYF2**qfTm$db?;XuC9un6mDghP#hPJNeH_>;f~OWWL~R{4s6-YD;} zcK%a67=o}+f%PA;ddZco0Y3cjUb2O_$`-3 zm@BWs@tE`2KFT+0ZY21S6$(!dnx!see+AvOuPO)10MQHxKRejcXJ)3L!-R9ei|UsX zTfR(WrX<>FSX`}Q^^*{~4asNMUT|c6yieDw20&QGmO zfI>kiacL+&9f$tW6m}P#9?T4trH9H)XuJf-l5u?MUPk-ic*D^YD&GJMttg7}mB;yb z4I~P+6;|zQAXt$u;Ruzsg(XPSGt26h6IJYcEV%VbbW$mAVHeu^$sqA9Hg6l#G_y}J@c$?8r}VJvbq&p0h8hC=-vD%VpN9&%?c=SNbKEv z_;wJzhJKx?DP#D5Q}nc(loa;v&bzpRnBa-6@AH2X!IF~9e*zZ-j3Eo@UI?P9J^e6- z$7N#VRDIg@V|faNmT>raFzV2*X8JyRoW8-m;@d60Z;3A#-wyG8O?=z&l^yFLJN|}!*6H9-kosMNOc*Ya=8q3<% zPbaeOmH~6ir-?@EE*fRg1omdntjw*-zY*Lxf=dNl=R}N(md-?@DI9}3*yGNuu?2sC zR&n;Y25fcTgR9|6XyolWNf__y6kn2v)<1Oy-@0SAx?Es1FSP#Bel~;1Y#k)6=Xn4brnW+H zPr?fA5{

G~zDNe7i)m?xN=FdJ@S{hRPlC-6}WAcc|PVPbw&o)8MlO6-29Hg12-% zIOsNYl@7WMT}5!$3K(z&scZINR6^GsaFfQ^6g6VfdzLNh4?Rn`xIVFkuN(w5^@_kQ zGeTI9;=kXVY&-B~c&?=*B>Y`pVUHi$MK$aCGn|y|^_OQ$ag=Q{qGN5)^)lQnNHN1R z6uFT0Ud_e%@{*d10eNoC#Wiwz&BaZ&U@gM+`j8?;R~3QXwMH2`FBXWwsdrbGA5nVi z*t_l-bUV84g1aGU#vRJlHCqi+m2|Z&A(j>`6iYiEFf*J2;&vV41!`tud@+a%*v!u; zx7D2``$1b>7uoAjpvlMn{7tw?ILOZ@vI7s8lYukO$%kKp* z#!|8&NMu(cU(3QY+QNe1_;0bFY)Fa`VI4NUzazQ-aENVy=n9|!qLsdK+Y=nz&{p>d z2DaK)Y%xJ%ZjFe$04(~sYU@?J) z_Md_?6nqBXT+z|CZ~+Qv6WvGh>8>VtdxO+Y*=Rmn@aG5|)>R>RhoY6_p(rMXgn9v5 zbNi@~K{z^~9r+BSOv1oc_iLO9yFO7yHcrI^7z$D#6W_KVH7r%4>k+`H9L@e7a6(-l z$!dZAE%K&1|C}PfU4)!%+cT%%E6z*9L8`bn93-CL<)va*LVKTyZ9y8bR7iA8!<_zl z0oW$sC{RzRW7Tyl3S!2=VSxGH#R^QWcjT#h^@xIPuS=mY)j>{uI_u!kzG0R43VY6w z&ItYtXCo~(^qjqX60MiJ+7Ybwt+zcv%S>C{Nqp75)wXTBMfmq@Kb}gnW#5DH57fT3 z@?^Ddoh|qa#Px_?s?pH~5|X?s)*EQ9=o01}#F>A7lJo;?b z)SoLzYfEBC*tPqKFEk-$OCA#hSle0(Kp(%e8v{geY;fF{0fc^vHB@L9(JSkVChHkf zauh4HxKMH^SWnS&`a{8OaKwhBCRj7Zk|v7L3DB#FtimFNA4285IG}(ASO$>gK*)%WgLBcjMN#6k2%Q_qE5v{)-kPQOBRMZ-L zA6aGB2mc7GE!crCh(PLE02uTZ64-)^DCdZ&r^O+s>&?;Af)$SK^*Q}f6OEduqhrvD z6li=J^Wd=|pz*J7@SWp@)rB~0Z7f%mh8~8I$5wk zsTXp$BpO9)){j~k-5>Ux%WBP!A%=DciNv8@Vuaog!b)QA)Z}K%eoYKoCcdqPY;7CXNqLT%y8XCGftBNMgubGCGz8kQA*J1UN)cwR>(B#$VLneml z4!3;!izFD7N9cWZb2NR2A@0eFj@*$TkJe)xdjA1dVq(h9dX^Yi*0a>BdZl+*l^fWl z;E65Q44*=FI_~B9P+w5@)40~KPtmsineC@ph=nO}SWpQVBE|EC0M*ILQX)^*T_$B> zbeukAVfC4P5AQiYJiilLKUepQiH`}Kq9v9qV4qpJ-~ z^c|~Qom&o`@xO-M#^DII^|$9q_S;;NeHF~>Fe7J3_OUR_VZw+LYjrI8n`U5l6Wd_b zo}LU|e%aF9;#V(ea#As`q(dR~g-);rsd7O$cnS_k|9L6a;h5Fn3k6AkARNpF-lV4y zJShT+UP7WdLr;mt{LwmsD+tng`JJxje>u`PH=ST7LGRBZdrYp|Yq zLJ%<)7#T9MayGm zsTXdpIvXzdt9oJdrcsqCOVMGbw`U-(G-95Mbd{q@TZ#_$BZiobJveq0nex07alNV`&guTjyB}Wh-?3dT7qpY{Axe1hm=sd_qC3 zFiEZX7HOE&7rDCzSQT)wcV zmpV7C^ZC_060A!~I-h(EM4wmlDu_OGA!Q3kGB7XM#3E7XKDxa_y;XzWVssvNeWkT5 z*DQSll1eG&v#4>=4=>^<=}nBJP&SVUi<%*tTFe~;z<)=BOu`l$QVhC}MrTdLH{3&f zL(3u0Af=PivDQJ7Y}{FK(=D1z;=7P_B?M)G;6t#@nCv{E{?v^vz|aQtG5dU}B`?0FeO?&k=ubXPjC#gBYJt$=~k zqF8AAZv%@BZ>Lpp6YbeUITn0f2RGcIHk;LgOIk&nTa%JQ1x7d~O3AJ6Yv6I#7u?En z2wrV=hrO3-TPXwA2UTwu`zvw_zp&Mf!hDE>FzmzY=xPQ_$K@B`Z;TuuNL0x6$>s$1 zN$vzHuKN40XTl;3`E>$6RI^AmQ=B7QFH$7o($;M;oYa*@sb=NG8g->p((%LBkqqQ+ zm6#1E8Q%d?uA^1QaE_oCvH6#vU{RP8@|i7FB&x-_U6YrS@WKxU)-ZxpGYflKEXqhU z*^^@Y%6Y6;{bC|(gW#>@i$vp8UC2m@ared3-yqfJn*z^4Pb{2oMXK#0m938SW3+sW z>ghAh!%a%prOiKfo?z!F3(;&OgVp4bRCZ#`LQ_rj2d(+0T1>3w%ATds z+z4@-shh$J&%4^IKGW{xq>`%Mfcdb^RI8Cxb@M)`{KoaS%>4F0LI0cOkS4nyUDAUc zKdA91Xtx=8vSFT&?@7bZ3d@OxhD2!UepP9j=jVyw&^RqD3FTQan$Q|Y^c;$#P9J{^ z32J8Mm4ufXo#)%#L}Q!4Cs<&z+20q0=Z2ORNo7+jd91 z`MfhzuplgnlIXk&(z`-y18(P9>kauR0L9gvkZ)IU^+|cL=8{7;*IXK*{0DL}wa(Ur zmbD3dMd1m{XQM)gm9tbA^q{;% z;AjB~_skd}&jTOMgIv}N;OqFM>-0+EIuWX;S5CuCu6RwODg1a0#F(!oA!>;=zsm>G zMe?N91c_RV64<*&ArLhw!!>2us5&IgFsQg|h0?IkpF4px2B9dw^FthFn9#`w3ecgx z;`#{-Fm-5Y&w-*FR{|!KlYs~*fhD1C)6x|qF2%4V{dAsRTpX@G&uM>13c`o1c_{U+ z4R^D`^N^@)n9cfHzDx+4Y!Kn!;pHPg1z2~9>zsUJEV*&O@1qP3W8%;=C}@&URw&1W zFJ$g?-i>3SVW?xMy+lLpIOM3G2)X>Gid?4*2AqIBkkS{kyZtP02jF}@Usl9-w9oA= z_W44d^SH4Dp4%!<^YYD|7#64zd^hPKj;|b@CTG~#O<~$71$5Sm$G>_vt zQ2eC)Wkjiy#N-}dmQ{m=kOq{k?sl4D7A~htsxAIpOxBy1$nEYxBV3bblTB z%kpsis{4cFUzit;`yVC$%)BS!{>R9FOWwc4{SD;5I&W7(EIkrR(NTFXlRpXN0}58NFQoDCPJ z#I{FW-6z;evH$gjU$|d=6@}m?k(?5Y$Rm0?nqI=%Il3C_4vG0D(M)~Y ztzYON`!(UG3sPFzUV`(ScY3;=xE!P;9k>@cNA1CLij}pdjGiY+EuHp}-63(#+xtN% zhf0AiNlZTmIxtq;Of-QRJgDo&V8$3*d$9&BP=$+066P>${JUPlS`dp|^`fcjw%(7_ zPmQuQ>u7zF+GbF@3`!4chdzz5g)BR)H`ULKEnNw6;<;ZV<76G~D}saa4K#}8W|{_< zdLXGQa86J=?PKU-lOE|`&Y=+p*K~TziTf>VNxEP|uJ^V~#7$-P=KN{tvc>H>qV%YT zHFhworNDKt+Tad((nF8-aw zJfpq*CEC3sXhfStRl&Xp%mZrlrRQ@?&&x02eCoWuLnBQAltyC8PL$1Z+JRVcu?}FT z&D#gWaU!}B**+>VSZD_a^f)N+C8Wvq^x2+h(h<)Xp0JBZmsR(7gFE9ko}>=qRb6E4tvC8!`{I2B|JQGtV~AXQL-eTWJ& zhzdXgbb7mW%ZyqL!rHByrVj7>M<#r`?|1&~Tg``i4Du^s(_Ppq74xSc8o*pf?L!-M zq5zbHX2iZT-HTAGme!%SS~33&z?j<5Sf>XYYc{&|TaEQ_3pG}zXe>1U@Meml!6D@R zhh}o6?7-+(63#`s{+xkYV3q3Zd3`CS3w6fdQ%~bYgfby)`nw&j&@{0Q*0R;M^!Vaj zw&tq?nVa7OYoi5erT_%vkDg^(F`Gc^S>FLl>}NBv!W^S+F&X3(zxJM=+tH3VaxTG* zmfC@Ah>tg)6p$-eB3fYtK`OXr@ZM1T7iBShH;iFz>Kl};mKHz}LfLyIX)L{a5@(~( zYpyus5heQD#wVQ_ z+KEQJmC1Z5n!E&8rE{-VvP4^8`=D=9lq>!GE`XQtZk(p;+t*O(sp!bi%qTQ!Gbt*r zmOFyRBX0TzfNKP~-iR)XZO&0KUs$ghwA)GL{yK`pQo>R>n!kAhZtafCRU+u9n`Z3? zj5I-+_&$`cZM5*;3){+H6gG6mgq_Nt7Ir%S3E6k>2H|z^M}?iqe<(^?DhOZVaxnoVL!~oE+ywC;apD6HNv@)oU7m@z0TM&L?3o?2}^XD#Z4b9Q)U7Ls{44uV+Pn6 z>F!U_Lo6<{I~H=49+K@c2Vx->5wdZrD`$-e@$sIokk91>+3LPR@34HU%RD!hu7jXh zzTIUmh=m-`LsDJl1+kEq^pJFy*&7S_g&vaOGB1vW)axM*mw9O{WTPIE=`t^mg_P?d z(_H5Dv5-Z2$PAZRj)l1O5Vy%r&u)WD&A)fh(s@gy7x= zR9OdWk99I;LRtp=`zv%68H=~VZWf|(B%U6TY9OZgj+aWX|AA5^oyF7Qdzdz*cu&U{ z6E#5IfW0pcFB%e(Y05chu>IPUiMb2Xyu%v8)fNa$L{zK6)?~`u@HK0J$~j~@x>#}v zgp0IkhL#b;on!bpNJT5hmO--lGq_l5)X6*~<2ThOL_cGH%j#~h)LRqX&?qp!xA7oyKWc1s4Q#Zy`fQIrhwN)F zpiiW#jQCDrjNhkzX;Z(jxuCwTn7g(>vees#*$M~D*b!h~fSq8~jpts_GM{>GCAKbY zuTUgjl&i9;okn9j)Q(1)QsKGoC?q{exKUd_&(M&cfNbmM zC8(`NwM}IH)?nu7(?M7PWxzol^k)c#UkyTS*J1D&3n7RN4PxsDW0A+tP-Y#>W*8Y} z4NN)Aa+t+1Z0?Uwh2}nS3O0w$VV{P58g@7AZrJBxpNHKCyAO6h?EbKc_MH-L6ZFMf zL!(OXg*gOsobrY|X2s#icB=7kw_f{L2+{QL7D02wVZ-um{o&2I{jomC9O{FVZ_d5Y zk8)?+k5aVWkI>SmS3zn%UyAq11-(zQs88I80t5kX_ri_0Gwsj7G~^qvJ6b=_sD3S4 z?~G`@{~ne#;TD4#>Z`94)H9+N>W4vY9|ngSpoXzN``W0Up`NupN@A;FDUf$JaOi`P zfS3iw4wDY!fN{d0tuxTp8L-n~r^8N#oeJ9yo8qmot*|YyEwD|n@!Z?+zR}xg0rFc6 zQx5Ym!8p%`^D%u6an3>uq?_aQ{peYj$GXAB zcSFJ)Klmw)*nU@t*8t8!mTky)Hmd`jo5uJceTiN5pd%*m)!V^jaJq!6oId{9U%>1U zc1*BbIWe9UG-M0yC@itfU`2)F^QyR1G7^&uPo#vUxH6_#QJQ$pMkZl5b}@ziXtuzB zj@pI}xZX$U;(#lDy5+_VIlXvj&kS^KJmTZU*|}?7+2YXHWd#6ExZMGJH*Y>GK+Wn(>LPY7mPzMt_D)TdvmxwfM8&@3G>|J_rC^ ztyQPLf7og)w3Ok{0&o49Nce{fI60JueiTRdMxG;F=L1)#hD{jmc!<-)kz4P9hC!q< zp(LwCz81y;1Gh4Vn_E#OTnRaj*)SD?v@TkX9Uv4N=@VU|ZCcLWg-l^7lhK^wk=7}27=<^t@MQHkR(KK(%KXbib4Ob= z&&lY={9pv9qKWZ+BIZev$3$&Yd9k*nvm`nWjmdCr2Jh+M&WXg&U<+Lm5pkEJg-b7S zoN%z#5t>(y$8GxF22~6mr?#UNhI+l}t(X_ve@)x-9M)nw>4Y99H%@p|ZF1EY*yHOb zGdO48TX>%&Rpc6E2u6_6tQp3Z+G+Guq;dv#2}YuMD{>3cZBHI#2QOdG#13>>!3<-& zZO^RKVxMi#4-%cn{Lsctr|aEVO|b&2>q6BCw$x($2v>rVXRFPVaUzPR6(Ik(EIS>a z%7H*LC{MpD(};$Xyy|Is6jjK7Zu9ivf((Qr`fZqyc=CsU0x))d6KG4k5h^dn0JxdL zphQVAUJ*n0(5EwZW(%L#+o5(EVjVR6PK|iO5El^exRCQ$EzZ29W>NEDLlf_34!eXC zOF(Tw5f+#AjpqNvB%172`^Hv%Et=Hy#vug7I;r+_KbmxyIE!{5c-o29xOgk&L`i7B z2@)RHC0pGZ0D^pLAnz!_yI8imBt2jq1%N~1D(fMf%^~7z)UtMfHh#9cI{*~u-+@L< z#bon(2MEH?Kf+gePqBY(r73J?ouH(a z*ARGs(DM0tS4s>eXbeU_BD}`64iUU>_|jroXO7&{UP@V`sp4 z>rRI3N|R?n$Zefhzs+nxUKP0+^B_RZJCDYw;>F=072pjADb8D8dWo;4yBP5R93!2i zsUZH~$?ve2#e*kCZbrqZ>E$$d`cM&S_KC4(SH=d!R(lfi)RigdN(i2!(kFa+DRXfq zmLZv`n0C{bEb1JKi5oHUuMN5mbogcv7bqNckYwNArdONP^@|j}9SW5*Asu4=qOG}r? z5@cgxH)=n~(0-7v{a`XrivdFYWr@#U%)X+-Pv*OUkdQQkpd7^_aWxuUXrbU4gdFrqN%U49-;8bmabh-ulEOr~9OOo^ zsXk7!5-$%x`>6!)AdYX2-6q0oKGM5r%L=SSVpIG{R7QwC@Dc>xY*IR1;vSkUtfCOn z5Mk5K+-Y(dlSG61P>oyOM6o4!U@5euKi-z$`8_SFd~5C!i-Na!=q`-7IZ-DGo#@hTO z{}M|N>WLjBaUjP;%6D*zggy!0>vMcWiwo*J;>oz02w@JX(o|i+&4W>V2gJtFPvWfw=~g+UXveX~786_z{4|RxE4bMB4+v9cT4Lv=sGmV2>w}aL3YGvg1+Z zO8!%kh%ga-jHS}8=p!iCrtlw$sA~}w{Tv5kP_7+|%V0ZjPxo$;|`e>5EuY2T9Jt|h1a1&#WgkA${!YPx}rvhn4C@yh=JjuvF8LmI3+J)&^ee?0gEsmNdK*JnK7mpEiigi=8P;GahRHCy-a1e~6ecXw$zOL6`m{t7lTd0yp{3pu9Sd>4 zKkTuH;{Jj@#;`zfxz+s;=+Ia|dAP=>zd9h)apDKCH0rE)t%p_HUFVe1u1gzJ0EZK= zgit!x{y)+^M%AL#q9?Si8^`c5&~nh_J9|FBwA&iRz95~XQ_>E2J>9uWQ*FWRXz~i2 zM()$dfj749z*J*H_9O8OEPobDd!WeMkwKeu6F~TW%1hE;NYmfj1vfh!L8|Lrmo_>0 zvxu*}mZVCv;3Bvn={exanV8b*vBV>^vExCnP(HT089+D=lMQ#c&{|aN_umBlI^kY!=|bn z!(tm%=~_l9X(dBaw_)0*|0-B;>gCHdyoZjNZDg}D88ZUSa#rWD-m~mDO&GAdS){id z;q9!IY~#`BJh+!5gpQ>FbF}N|iKAZ~JwEcVa=!N*>jo5V%OS?z`-Smn)hHL>Hd(4{ zF2HUau`mk};}>V9I#0l5fy>(aC#doNNn&rZ_t-~NPT4^yAWbsSu{OQhH<{Sm;|I~? zqxknoe@?u)g4dlEny`z!wXwfnvcJ-Yk9fpV9-T|8`~p+xZrsV8@khYZDU6dGLNhbQ zeCPrR--uiztRwmcvUbw`Q0Fy5$SKY`_q`y5oRF=ZZ&;FAx7aX2xmw&Xzv42n=XD-j z8WgG*qTcBZ+gmgHJwH|v3}gF0_Eber4e?#_kX^6HN5Yk?5P(53xeUwzSFcRBTJh5Y~h~5okUytV!L%y7@G$ zXPz)S0Kz;{Q>w5{P3f?~mYOojFZ9*h%qsy(n&XWW*^~-jo7sZz2xxb=nXMu=w#L_$ z+Z#zWLsx9q)ySKc0thqJ0-Sl5po@h@d0^X%v=AqKa=ax0013hh1D{MV0m}O_ZSli+ z<-Ju9fi2jAu4G5mPq(&wl_al@|3X8BZCxVFLQujwA1Gm68BszK%)JQO>L=n@fuMC2 zAdYowz4&Ydaje_29ueO|*w%Fj+qwy1Teq$c?PEte@WukpZ{&wNd z9`wH?{8QuprWtTyF=r1vspp6^P16w8NFVw=2XSxA)gsT!O(9tMEG* zp8_p~$@=dUgbPm=RnqB85#HO;-b2obJsv!?JfgM`ZSIhw&PKw;<>B&;$O!S*(sNFy z;TYFQSWyh#2d5akwtiYfYB{1l6o#`M{1?jB6iGa7a4+@1pJ^{82CUfWLNE|JW=Z4Q z&@=ipoDCOi6}trz@{yhn-Rb+7eNdrJ$B$OvG~-_7JZkl2)=}FYLq*7xjKhoyl#K%z z?6M(rI*0^(I^`HUg845|DAeDe37?AdofEjCaZIu2F0m?C#N-dd&wMmUiF9O|;KG{V zW26vxBt$!e=rQhlA3XOG77REDI;$fyDu&DrKqh)EJDc@4+a7CTMFq`c;brshZroc3>+>E2MzO{fr&wlc+CQ@ovN~*gEO_sd-W4S*2b=PJYRWT66>rMd z^rj?X@55KC7ZSE$*=JNz8=E11D2)g!l%jk19;Az{iSL6`tci)!>$|-r^ma;M?;~Jz zIM}-uyu1{PB>J(8Z|zTS$6_Fr74&0&dNpJY*q_>&ck&|U&0NG&F}&16mTzrOY156B z!V)hDl2AzOy_MKr+Z%>@nl3v6)MVOg(=J<+r>mPYr)YAbOU|6K@n-C@ne`8$1({ab zW^euj_SskJ`|P=Yu<-dbvdOUmj_4jjJN6_?Y@_XLE@zNqKqB*qiEu#w7FpRMYi^MR zcUNd>7bz}!wG(VAIx^-!Cf3kBme3qi==;_sMc$<)r6tR-qt-fxb*}m@X@sY8-&=zX zeBp?ujckj~#Zv{UJk7^9o+bV9K5jtyK3;T=t_4I9;nUFz_1zV<$mO& zR%AfHQ2}j6@qiSTO$D@U^6o=a;VICku9fl>)I+h|If>$8UAq-dT9T*GD+y37r7XZP zmm^`s$3J)#43^egK29sx;qNSxNFw?^vi0%nUK?b?dr#r&4llv#YB)F6pAp9PG&mKj ztkC{x;+u^xJ+6+i+4Wn9Gq8D{$QJ`2JS{nW2*Z!D?*fKh3?QtP9zz)@4rl0B6^#0O zC=CmyWhNZ%xDa|a6M5E$@4^?GcG+BW!GOz&h4$W~q~Se*_fTFAiJyQSYk)0qc1=Lu zJ#(jFb7P~Im*~;850i*8@q1y_=nL$&Y;{jVrpAmtbCXOpwz_Tb@I}AFfON0H6aNLc zdh0-`c;(;AjM~&Bc2-O4##};oQEYW90qr^~Tc-)sY;|7vwY1YT_dF|_L?nhhJ2-_J z#bdWUb{!fx6m-Me5TyFxo__FqAi9Q;Y!}ti*<5oWnKaXb8St@0W1IRgE`X*rc&FAc zIbUD+cXj17JR?O{XrlMn4zzgr22za%$xLTqDl_Ydu@I{_x2xUu*bB%Qu)(SU47P1M;n9MWzb10;B00$n$kAscDA(Bb zIGu;p0km`rUR75GG6|twRKHM|N{#_8(nJ`qfjpq3!X;YL7MxGzh)fe=c*-~8_MSH+ z;(769z!?G$s-KPx&dqW~dA3I{VCmRpK|CAPFh<9+ez9#T8x@*so7Qy()P&!w0%=Yo z(rkpcWa?1R z$@pCb(JHMHeqjgi+UM5}Xb>M%{gHL+NwT`By(a@2eJC>d?rxkz#R)irXbV@XZJUe2 zB3XhVxIpiZu0gfCCJmyFSD>jwhapXGL#Qv%fB^0~=0viDdl?}=$F^sT@e|`aI{qr~ zzsj(SdbKiTSw$$FiE0^J4ZA1{{aX>T8(VAlQ@{Y#Z14YW%^t+K`Nx{AqOjpLn@2UH zr(BuN{`4_U{h&}_n8+|zv0>G^5UZApJtc^J&lLti^~QIoYPbVRmHMaE*#U-Dg&#-p z`2tHYhlIo3Q4Gj%xB%H^wTO2iysX9R3($+~v5|QkkEzuCEH;Wnuc8{Q-f&$GCH}6i zm955I1nBx?>yaq*W4&N#I%y+hITIDtyI3E$qN7KmIihy~7fOkrfwF76h#hHDr^N?8 zjwS`Qs4o!pf(z1^xIBMV%psDpM%^!9MC_d;bKLX>25NTnuGsLj zz*`c%EzWI-nY(eWDmtcS+EqfSIFr97(q~ZmLvX4NaUsge1R_~tP>_Z+eqEr9--BDA zIAgE}0yN?N`S)OAbYF8o8PDtWwEUq#bZ8!X64?e%Kx`>4>{VUGSH-~c2f=t34j!Y& z@Umr}8ShV#0FIr*O+DPOV@VKUWp4;BS+IV_mHnDYa`Jp$y5`Ky#I)v2E9G;*j;V|e3WR#cb9%j+D`=C@NA4uj8wps-@Wuek}*g524pu092+F%DeE z@yRFwkNM-`^2otrzpG+T?2K3JGs;(AiWL>n_7LkAsKJBN`f-n_pTB}h7mKSBEJa51 z-H;CHt;X8ehtazsOQRo%6L*Tz`iRtV1)xnCqa%ljb%dAiK$?>1yZSoCBzjKow=lY= z#_c6&UWk0qP5kyD93t#Jy}gG--dFKS zF}UPGIR2X!wEI!q^SA)o5pr+5EvnNFo|js1n@Rl?wBzM>qOODOPP7C4^kKrn4~4K0 zbvzkb(it7ccOcss4ef*z$mu9wPDLl#l1@GmRic+b`35RNZ*KivwE$!x_!Xf4LL))6 z8Ja~Wxhd*=tEFvLIz>fC!($51N<|cc5{NQqS=3cHH!;M;mLy3sW#O`WZ^w1*?9e2s z8w{wuDw(yEJc)~|rp(CAlvNPFFC+w0*stJcX|M1}XD;A)-TiQlTj9h#%g!_zzE5m*{)T2(^t zN33NTX?_iD+kE^H%+cbI#M?-tmVQBJL{Ci}>R~`0_%)u49`{_F20(bR5TKO?Eb={+ z1|&yHGr8mj;rHu=4?!CdzJAfe$Dcxje4DgNT0vV9_S9BCpWKY5rS&|v?z9WX7;Yyj zoA;Yxe5w0&ow)u8TkldD%Y@`*eCcou?6-qpya>+!312z^L@%Q){G!YsK~S`Tz>|B+ z2Xp+c;oA99e7HKPHHO+3hb22y`RW}O`6|+=Ux8fkTwd=bS`0&Lho0ffr{C%o9a5y` zbz^HbfV+^?(v9T7Vim79VoJe94J=(Sm`MO{!9q1n!qcN5#?Nq2U>Ul_5j&EAFPZIPK0xYy4HX)3M)6aDUH8GwzuHe-O{W{fk)dvPA)2mS(T}L%%mzm@ z-Ia#ROS1*111S26XjhVBW6v*MC8jPFvh286LBITUWb-mt3Z2PqfOwlWY-hoL;`3M% zCNX`kxE5*#luI`UbbKt%*Q1n#Qjd zbrG}s^>BvhZnZdW*0Io8XgW_u9JmxegWc&Mm0xyZcoqKwaRhT@5QeXXGx|rtK4Zs* z^zvUPa7K;fx0#84T+kZeG^){;aOF1%<4I zC?GaqK!M*r{tVAGP+I+tPE2eM2@0ty*hjXL^g|K*0E@Cab??;P^S(~|w$1rryOjcHk`g_(8)X1^r8 zb_Bl{oFUmipC{SxUsdi{wPww_2Uf`su3JmcI99~J>C!{^H(lC*fAm)#`!_{$NQJR~ z4iQEnkHr2-BIZ^Reya$hv|fbL->jHDS6VGS0P_%(!&ggHB5t9yPTKenVfO+`MtB^m z81d^7GCbuhNs+z>vjO4scQ@Q?P;%V87SQxJ3n{Cl2N6d&u7djkp?8>%`1|2gL|8oC zDrxPo5FKC8ioj8lbiDAB>H;6in{bGit=rU;R1W2+mmMz`v>?hPI4XzoSq1DBU{M}R zK`?~vkbg0-C5R2f!u-gm9678W7P=Tv!~KQ8dF`+?#fZP$Pi4o;18s|PpjIOCCO_pz zxKloaE2XE$FsDEC(DV(0ILh%i#Zibq2RRHV(S)eL!AE!NsfB%kjWj%J-BFKH(UD@>kzq zrL3ybVOFgbPLv}de+l_go)Yq+d|=i}g{vNskO%B4N-N#HYOPefN>-}M5kdJ?Jt$m@ z14`9~SeSox`P$Vn&tgS)6|P$=VvCiSy-KFE64FV4mjEXLMnb%FkK~aSfqFdB0_p#2 z?`+`XsLK66ZBxj_A_04~V9|vXh@~$xv%9nJvq_UQiA~Zao3;T0lWlgAUAoy_cQpL5Q0UT0=&9*{7VE|1YO~XwK;$KBM5wvpzESUqAY>d1s&V@%iU|;**y1&M#bW!G#wUeQM#w zixw|g$_t{^W|tgJm)qm@$^PP!Wu;~1%PT6YKE0y4rgmlElDc3$p8RXL^s>tvueefa z3axDpt1YdO=vC`tZSh3%GpTf@y<>f6*VUix{sw6M{if?Lnyzm(UEgN9rk}hp(tO->O)}CV80oQJ=YsK1{jp&7 znffh)-f7>d?#H%44c_;#`IfV^e?mH86^@)6q_?Ca_w$}=O zbh}3WuQg!Cwb?KJgP{}p7%fQVh8el<%o!*4HR2y#`oGrYFZBS*X)eA-j%3SS7tnvH z^jCbQhd;5>=0X*4xoho;{)bPF>$!Hrb-mZ$@cE55{`*aRU%2^}{x9Bo+os#^_|oS8 zxbw?fzH--Bx88lvy#x2%|Fyxdf8&8|4?gtp&?ApNw*B!Zp4{=&H=iE<)-%tJJoo$y zJ74_vOQYX;`ITL-e)oI3U;F-^y|4e^hhsn5_v8IP`RNhDRLqF9uS&5snS~9Lr*rh|E3N0Nv408TYYwCN2DvJ%QY(((gS9(i z)nF$>A&!p8VSOucJXW_>j?!9;FeQ*i+pE!@%>okmOFK1^uLcrSK^6;JIfj{A3zN8w zg^i#jXzk9jS$d zTnG6z*)!N(QR!)=oJNW<7AC>9z>U(QwX#t%+8gHTX)&v(HsnovSlahlFv~54YYeG< z3bq!c7l)n7Ofr!RX#mwHmFVc2iZdBWbF_Unm5)~O=9pznCfdo8TuWH%k{%iDEoR$0 zj<{4}72&A1T2WRDa!4XB?e-~EE%g{ot+eDy>1sZ02x&-f=&O;Bkj>}VdPS*BZEs53 zsP9t9TMs+63)Q{mqt!6g70I{ce?>2*mxIri!;s0Sw_}wcJgvS(&Y6u*tsP>$LMspT zu4AQPVLC^8YsivoKaq1}(=+5avG!Y!ypEmY(QRnXPx=7)QBR^i`a$xuXY)%!C$+Zk zKw2rJNoPJW)Y{QK$LNc>8q@SpZ=+ACm9rblOnMG|ExQBdq>IZ0yp;fOUT{{STrqQ*)v-G^%5*c8&7q`XSXmjS3lz zr!`BcvJhFc)E0|NoS!( zis`JhM!WMkeWHA5er`d#Bv{?hs6lgG5_Y<#QJiKcn(4Hfq1i(l-L*KRUAej-eV{Yu zCcGz2XBPP|>5O9Ney)I49TAvxkX-=tOme@ED>#eXVSa?%Va|iOb$~0N!~Ct=QmX@NO(H&<{T%#p9+_dj56g-M5by)dta8G$(o zvk4~MGb)Bz!}k|_*&3oNV7?UwUt#huIR*=YMUJyqCT~? z)e_7hOOU=7^+qYTvQRYt(nzhvrnJ_v+FXynGD1_^OwFMj@wBzuc`WU~l+@fv4~J(x zJva1R+k?uRbwke$8+zu>o{bZ<>#x5a2Ua}a6X>Cz7%#fW8CcVU^D!Kv1p*rp%~I5} zu?Mj@9HT`dk^KBqJCn)v$>fytGkO_@UXsBfq<+S?CK?YX)(11%O#-;DN~@`rYp+t9 zGga}HM5>K>tUOvhT1>HR{YO->}ea92Fk29ZJ;6=$%Pu$s*k?O>tm z;hKyv(Refy4aK5Yt0{}_+oVPevHzk-rm*iT`1JZP$z-Yt$aPe`9ka@~rerLHI|XW- zibpzd`4yJtSR&n?Qnm6;_c!@ACEDUq3z{yLjU=GZl!OP@8_vEpmO=ftCOLH$`HkbG16tlnA4J%j$8XwhWoAl*Qlb*yEr zPmWExCeZbjxWUm4E(Bh$kCSB|cLA=Kg2musun=^2Bg};`DGs;>6ye^+BAAH6Ms`HU zT)=S`fTduuypTf_%qqAh@aJM!=mDL@mI^U!6wiT`oKoe4U!-N8bKLwf(0NCOgxA@zyRn4O`r@|00+jlA#bn^41%qoAH+Zy zG=NI52+RQ!4M5|TCfUx+XZM7yIZhQ z+t5@=gZ{GiR?G5eCnqk!x{qJVyOs(z@=psfjICG~WimMiQA;+}hv(rgStZj&^6#Om)`f zsEfA5R8G%Fvrzg-i^b7ha%t<~4S$nZB)7@R71o8q(L{-EF4N6Yq`kuCpge*VcDo3( z##SPbeR-%YM0!vGRYOG;(oJ?2t~t>TjVLThVF}p0CX{LkrPP{GYrMUU`Bzwj6-a=k z$HQC|4A|^2D=>Jk6PzqenTq9QraaV&!cv+6Q6!JTWh!RfOvoiwAb+ecgKCFLZ4hk7 z$mv3AxNfKsc&K?{Thbm6b!d8!X~QZMe#>hE6siyf7g*jkTHZCH%|-qzQc<;)6;msx zf|gBXkbZNdEgIJJTrWytnYCmUl|zq1nHR38vDxcGRBkqK76zkXHI!;|H3+UYl)kVw z+8W7JhSsmcHI<3hxCqW4?QzK#6X+S8)tdu01ZbvfM3`FBdog9(AJ~pJYLD65* zN+3nblF_0g9J|2E0i#YfLao}KNwJ|*OP?~v$k)=2S&!1Dbg+kEd7Gk^n0TVSHKO1d6qPzb;TkoROvDxPD(S#bPD@{MFNx9Crc0@WP|6Cm0}D8o z#xdNLN;TG|qCXtVZy9BmF@m73G`UJcsZ^Iz67OnDq>j#SC3~pH2pe1<%```p<*7s) z%?DaNk}jl`<#=*rO4~9AlAqc{w-nYV5=u=dj+)3;AS+AO9f2v%nou;OSfOxON{7>2 z;mUZdOA)mBr!*3Zw_=Q~YK=o;Wmzf_!kP$EjlOF|0!RBXrOpN@ENP~PO%zgttRv;C zr^$v|vg_fpc8mwuB88_nQXx}8(p9FAYoeKmu9eD)D2=s8`(q5A5(ND|8jGo6LoFdo z{3^`kIR_>Wx}{bN%dn6~7glO9;VVqFnLi3deJ~hHWQ;b^)1?}~DF8Jw#%Z)Yl3t!j zLBLo{>t&ihtAAZLRwptl+AGQ8==!O9EmP5z5=pJ2=lXO`^9xIDN&qsVmbC!_tAhm9 zMb^Cr&yOicXJuTeNKxlxekG|k5=R@LP$8PU)X!OJdOx=*?7)J?l_!@@xz*Q|RMl41vN_PWrg_!4wwkVOrfZrbjWCkw8k2Kj zMM+J0uw-?48C_$&rjR13@n)2im5;eW*W*~0p@do(Y!Y)$y4zKWXk5t{ohKKUxwDB% zi#s)(5~9)?dFx?yM=d;ZqFq`xOf-z~eqFSAou2PnYJe~r+-y(6pN@}ow|GLyMBCI@ zw2kRJD^t!v%cos?+DmEHI#M<+N|j8caTvlLan-_x!eO+o$yv`QqiZtc!yy8a(A`t& zXWG%&VWk6VYj&rF)AYC@EK^WABQ6zH*EJ?LC85x$qQ_(Qb~+Tx<;UExjqg%Z3XSkB znhxjUYkp}3qk0!6O|%IzMxrdQbO2Mgs$qhC|%ib7^SCfRbDvDb} z!(c#7;53fPgZ`>8&+^WUicUpt=Kjn^r)r$=VLA%M@rRynH0ohJs+4U~L#d3yCQ?n_ zY3^vhcsilwSBeKkAudY;YXc<{TBl;qs-oqh*u)f8CSqZ>hs`x*VV&BF9-q`|1bHt{ z;1SC8ED@|J*3kgaV)WaJgwjg?NJch{w_q=fjV|eC5G%QLN+y9tNCZN#3T9=&qQs<9 z3XR$8F{hAU5a)hvOu&{@f_7POt5cI$M^Y56jY?XOJ)N0$Xzg8x9FTk@gz}Wf)wV7r zjlqm9XbM>ykT|R>Abob`h}}F^mXvnY6xBBJq9W?`3t4G4NVJep+8kV~wi=o1`QdaI zYZ!e!qA(lMrooL#jp~jV?LlMiTDHMr>yc)Y9UB^xmFm;jr)8ZBNq0zYGSQ0)E76Kd z5_`%trHaZ{lI=Lu#X*DahsBo?r-gGzG_Chv76%7{8Kq5M-soXdY8%u=)9^S=T@h^+ z#`>~0wzIg+*psxh$CMD87>rQVsWo|~`BSUWFWgM74R0rN16c zttGv-i{(urRBBmdq34mox`?_cN*rZ#F;fmb8$ArVFJ#o(fUO;`MtOBVqiCo)tS=Sj zlTABY@$kfQS@YG)mLXY>7vAKRtqZomq|ruMt2T$IJu)=3>HcIlWI%8`tY`bA?EDPv$5E+*@f~A={`N*;Ad*ny(M~J@ zFx_`D*TQP6)uF6_(n1bxUyeP1ie+w!iiCNfUBy%Nv5=x~*U61mE7=nj*tNWysmo2z z6k}2-rmY*XGRcNblWT6w3|1)EWb5g)rdwSY%SwXg@Y;DoRYh$sjaJ$s>T$GkVuZ=4 ztqF7#xSEGyM`D9rjJc3S0~NeoFC(sS;?wge_CBbdHUN2Rb;JJQJQFSCx?8Nq5} zsMF63w4qO_NVMWeL~AoTX9z~3Y79D-yT+nF&E6Hz>nzF6u}qaws2yc#Y0#!o3!$gU z^ee5MZJ8obd+6s56p+r26g?EPYr2tcYn>jarXm-+=P3#qvUQqeZ0gbflbUA#Nerf7o(&7-=PULM$u@ub|) zB0b%#R>7W|)3Ck4`wx^i<~_qgb0U*xO;v4>$+fa(8JRdg!SWpSNarayN5OUjD?7tf zlCgH2JixyKQv%+=z}TYg!^zG@MEKP}8&@Y{?N|*J;z$K6p;XqsIuXTw4fktt6qbqV za_MISI9s6;S-K_3WTQ14DGJ>)#R$QsAvXGGhXRE)?b_O7RlH5RLf*9rC6=HeLy2JJ z!4@kJS}ViKWkIEOWoM}^~%x}v?VdSEw3vt*X(sGOKPwUV)9U&s#>M| zQr)knB%rX6dR(%zG+_@0%2C}b1NBuase%hjOKNg9*lTJ3gY^SMRYDnBY$ijrw!ywo zJIPUw-WZaMR6|(nhE>6IEt;;arfZw&+HSg*^y}J$c64Q=i-VJ-!nB!{m*u6oVUeQ8 z!KQjW1Tgj}EDRQosN!54wuRKg*JCqeq>lzQ%D`F~eP>mij>Xu0A?4XUHAw|PVX@qpj?2g4|R+Cs|W#ee-jC`5g)fjdR7m9DpP}5H~ z;8zlhhSE9rTv?%T0j)2kLtPefhsov>vaGsk;oS@IS#4c-{laS&-bB|67Y6VXUSu+_ zz0?Z9- z8FU~DTSB-M{C<#TcVwf zZRrjil{eO*0kI;V=DQ?`|8ZyfXB_wBUcvn^{X@?Mjl+HrrAHX1@hST)0zQ8|>NiD6sya_~x+WJoGEvf14IR1ADjbM*c>8bDrin9L`_x z^Z(ok>y1X}oQdB=VCBG1J22C*&%%4Q6w0tq_usDjAJEM?uj2Pl5q=&_8(=x;bz;ai z2ae~QtN9uAW%hd? ze!uwT3#a-|moIs7PWI24uBV3+7w5vsrfd8X$`pBI+tmD~m*<*>ss84Cp2dIN^8zrJ zXL|bETBiD&g!|gNsg&9${|7Mp4ck=n8%X?qIW6XO9su3^UVSbI8Br9ZiYRbMF<&?@(i5f?K+1~ULs z=E~#ESO*2@d<~1xm+8H2ll?_g>U6pn3RhvTeFJmVj$Ny+7&$2n%=YGrv1U7t3qD$Q0Vr6dj=mcE!*A4}sl z3%wux5?v#(_73$Z*|Kj`f17OVJ?nXt9+r9SF|`uMb}44w>C}$x z#a*+iRUC92<-R9xRUC^}2ox?iUR7QmjZp(|_mOMsbWX+>Q%bY zfvqyh&1C)_la*Bh_X@k#D(;b4b)jfl&E|^dkSIT`c1m&RjCKlB4Foe`&5`5&6YXX^ zS~#sJCGl_&OC&Age^Wc67%Dws$u(=K;Ow_ONoui%dkwlp5BN<>gZl`D)LMyR)0)17 z<3ck?`tmp)b4$cYfr9MWuk;%3%-L&js~xxQQuT=%JYg1H)`e5XeU$sLf^)C3@|Qw+ z=`ixU%!Un7CY9*ozBY?>qkx*iIXP~}HLI*FXo%ZLs(Ks=>$UP6)9@+%3|*m%m9i_1 zr%q^zUXo_zr^Wi>S=FUjscTY0?^mAuEz$iFsx^fBK9jFb)!NHHs~Wc? ztD|f2@M{-*FPOasN~TgS+}xw<4I$>`)n#I<;y9EHb9vAfT_qB!+c81>>n`7@n1^TggyRCvHyUD`G6uFR|N{R1drAFn%f7= z@EJHQYa1Y1Bq*a*5oC&+*# zh=B+QgC@`j8bCb=fND?%oPY;KfWlkAJWv4gz~pUst{Y5%aj+lk2E$+o;6KY@^E(x8 z5caKLGw25!K@aEz5zqiCfelzd0hqiM&yItGU;^w1d%-TS6AXjxU>g_!TRD5O8=?{V7l$jVpxOsr~2&V)5-WdDctW#mq`6<1pN+!LhN+uoTli!Dc;YaCG zTr$r9ls>69xt$5l(joWr0J-Csn1w6R?KJk1e*jRNIzZv*-XNLSp0V^Vg-LnG0J*mT z3rK?b0LK7KRw@U{(*sE6Yjtx2Oe)KDfc$#_rSnCA*OIuqbo<>fNuB{f`F#ygxF-S0 z_gz5#KLq4I50ygoLr}fc{-XHlN6vn>%)BP2*Q@XhOG~1-n4Q`8u)87%{5O7P=r+;h+zYXD!2h9OA_Pa60Q+X*5 zGK)GepPv8-%08q+=Fjxs)ichq%O1hH0W^Xp5Ca*o5t!?HGwefP1ndP9U=kEOigRO7 z45~prXaX_N4K{+!U=Zv8JHdW%2;@J;6@Nwtzt}1a^R(U@w>ehXD6DWCruV z0$>AWAOIRb1Y|%r=mq^?GuR3S!FDhVM!^_304BlQCy*YnflAN_l3)`U07GB|>;eJNB96G(zy zFaUOdUEm<#zKL*v2bCZUx;z-r z05}5jhmjxPK{03mG0+RPfbC!ejDZ8-2$=IN^czqKnm`6@1cP80jDsU!-ZPL1I6*aN z1QE~)dch{J4UB^Q;2@X;`OhLQC<0DU2^v5Qbb?;62@HbmU?^ zf(Yma{a`B?2D`vGH~Iv|`3j!bl zGN2c11>3+d*bDZ91AzNB;)1z=2gRTsG=U`O27O>N7zD#$6zm3LU>qC(hrkh#{}SW? z3jhy_K|P3pKClUF1;bzz><0(IB*-5{Tu=m@pb|8J9?%Cig8?uEhQTNp0|&t*DEJP> zJFo~iK^X{uM$id*!4|LsjDr2(2$=IS>f!(BL+du0acJ!ZddNl}!=2_8{uu7GXQXE; z8Z0xo%P?_FXc0Iso`S(|3dg!Eoo%sr+IK!)+IOd$BP!lrT#VmQNF~yVmds+jFyIcQ z+m>_)=UZ^*A8oRp;GG@^T#8ucj$N&+QiWq5?Ep+Ud+ zTkND^bI@)x`7`->d=by{E`Aw*86W5S_^%h`PccM^1tNY;g9e$gbM|) zaJdi?t`+VO?h>{O-xPKU`-F4EP2v{ue(_=PGuG#=qt>^qf3g`Itm@4!|Cuk+8y1F zwDYshe&?5+i(M|)L#}VS7Q0>UL+*Fo@3|A6jOX7xeV&Is+dWTtc6$oFquxEe;EqvEjmvbab5iFl@UzV$+@-&$pDwDwq^v>vp+XHD4p zY_HqO?9KKu`-J^n`@cvFq(zcVS|Np{9_dEu7HPBe6=|EaN1BvQcbw;Fa|}E3oDI&8 zyQ*Bzxqj?A=(@nY%H8OWxa01t-97Fb-M6?my9eCga6jta;oj+f+5JQJ&)mOs|Hl0h zPm!nAbF*iY=NZpV&&!^1&k@fjyqmpGdtXF(XZtSkg?z2Pw6Du|qwf~q?Y;ruqrPF^ z^S&|PPke9seudH>@xAApEuSvWmCu&XlNZX8?2(J*amtugVsx}S6T11K4{%z-Df>) z{iF3l+ugQjY-iaI+7H|3NEb=hNd3|s(vbA5v`ZR;R=gwqSvt+}F^9)de%D>x#L%kGn}%s$9b#sC70s8R-@2HR;2Sg~*}FahGGj@r2|1NdJ20X6Lt^ zZ#d6&RlDk3A=jYmao5wXU%Jk53+^@UE8L%V?{e>PA8;@AxIAG`x93i@(Ayr)yTp5m zca1mZ?ejk39rnKBo#i{-SL?gf*X+yqKIilM1O5j8mHuXb)c?Bw$NqPzZUeY)2IG_b zI(|KW1Ai00jemsy5&tItHh-A^1K)-I^>y)a@mu1H;%nj`#F?ng$E=gq+ij}-4f{;# z%M$09>-f0i0*Av<>u7YWbzJZ0bKK{6%JHmY)bV4-dk(+zHs@o`W!`#ki?`GJ@7^Kr z^WMGQUwDsrPxH<9E%6om>U?2ehi{|rGJl_c!2f{%G5-$#uz$q=UnE}>{*MJ1XYh-8 z8}H=3d@*0fSMt?-fWMR9$`9~^koYX&T)`>$g)*U1s219UFA3ifb_;ujG3ds)Fd-a( zen_HMEEdbeO7UUq;cZN47U?6Sm*l-nC8IX4ucP7u%QHYwfq& z@3il=|HwXWe-k?L8~c0qCMhZZ+4ZhcW zR(ZAjMgL|ha}xJsVf>LlTR2rL5P8uq-fw-tdc^u?Yo6^iTY>GPwsUO@Y!_pkbJ>b* z6}FYOH8#bz&X%!t**<5x(RQotE4Hs={Cmdsg6%sP0onK`xuq+lh!lsOUngynwn+D2 zlz3DcmY#>czb=hSZ%S`VN2FN}+0o!gIWn%#x~_F?bDilv*L}PDVT=tGo>9+5-j^}j z?eoo&8|9Zt)*fww9^f;=eZteir0{WZhxnFwmbK6Ng!Kp3Igs^!+hev}wzq5-qE5%` zqta~08IFq_0mlZ%HyodKu5oraKjG?gz2w@5dOFLky1(GQ-~GJ%9rt|CMV?ijX3t|7 zX=wy{-Lv2GGtX~4?|No<=Xndg7kL+X>A9gIh%r~N2n&QFVG;DeE5wAPkP)h-fK-p3 zmXr`+D^n$Ir(>66uVcSs!g0`X*fEKbagKAYbG~zdbCJ{L^g7F&)y{fnqciM`Is07w zt|9++T^o1$NBz6}yZw9pWB&dAasPz>fd8QXkpHm%h=0;goqhn>aC{!0&(Glt__>(d z=JOVQ0cN;GnB%5vZ$00@H}Xw>m-pJBk=5QtZ<9Ca&3L=Lo4jM_rJOI{SKynAzRLTY zzG`2@*NeV7=o|GN@a1D<=VhK$X0-G?0ZjrW11JWS+$dI&M+JSyD zB3T@~qZpdo*yb2=>~QdIn|sLP^m#F&mH8@BQvvkt245p;EappM z1n%^8`+8XI_4)dJTQOe_`nLIoeA|6HFmI0dc4EGq#Lp1r$@%gexj?qa3*;hs5o*{b zJ5kHUa+zEyS7Yw1M~ydP_6*ArIVLCN4C=pI?vZ=tjdGvd&)Q-OX4Cc{gjN{qndxAs@hMG;2ddwq@Xy33u;*a^0{*1rV-;LJp^>4%&-tXUpacm3Pe!xHI-{wEz zK6D6kJk~=0xP8dRMweoJo(Tx`LW9sKGznoLqK`S9LbuQ(^a>k=KA~UOBy1M82wQ~# zVNlp63}M~6Ll_oDux=T}`gQsYbx1fY9Ki_6iFsnaI0qyDTydT_U$lq|#3FGK<^h}N z%+6xfVnD1H8^lJjNeqh-F(xL(jMyo5i#=kmxKZpA`>{ISjQM-3I3Ny++r%MpJI3Z= ztd4eyqv9@cx42gv6Zebb;)HlWJSZL#4~s{{Ns+VWS@W%PtOeG&)_GWgTC5AKMb<@_ z`E6FG)oU%bmRT#U)z*Nu-r9hbX_GZHl}`%m4y6d!P8%`ey3*W6s>U_s*SpbMN`xbI$}B z6VlBY=0uCuyQ_DnPTHVwKW)!0uCBFfH1!E**eWq*2RLre*c?YvFm?=otDD*aY76}H zTcGgPZFN&yKy88l(H7{Xc~I}L8~>v%u3om<0uN6M)cl~ErWd^e9Ap7d?J(?T_E!9Z zjrL39#~S;3c8}OI4GZ-O3-{G|dj*FC2Y7o028{G&KV7>@$L!=|eqjN=!9IZ_6urHy z5BK$s3=4=Dp^FR)RE|}WkA;PVMEHbwM+W%@M<~ZC%g0LVtH^q3B6IFJI-jd{nM`b@_OxSA@ULFDxX8S5msJ8uBqzTRKFE zm~^bBd@Lv+sHh!k$+~dguqa=-ezg^yx4& zL%h8r0z!h7_Hk6sSK3uRiS9)``B=#|s4we^S_aqd#;QJ2A10rLZaAI^oh2@b-(fFr zUes{+QW{TBHd1~T81o4T4-NDh;T;m}7cf|d<_-=F2=>*5g!%Y}1q2VqJqQo=^$ze0 z@b!_~OLNzALc>A^hxvww2SoYG=h)r#oPgj6->^V0ZxmDXEZ(hd#pmcELqmPTP{}|a zzksmtqUX=vhH`a*A;ZhdgIRCits;IQVcx#FNYtmh8wA zk6rm${=wtQrPHwoW+o_=P*H6GwFN4?1!$aKhiN#o-%;xw5UB0Qy0CtZRiQ5)1JuBt zdAx=N70nhnhjq|mY&W#RE2L(qwt(6K|8FfozyCz}_wU^&CNjg2o)L3o*^wPbb|2Xi z<6}<9Of{G+88K1DjLf(cZMY>EuEW|X!1_g z>mtl!4JK4N+>(xhSX1N^k2EuQnxqtSd|ZkyV|)fG$ObV7{(jsd4}z9KM{mTX5G~G$ z#WmrOcNAK~oZc@XIWAqBU^Zn~v>gZZ=`%RpJb|$mtR7MpZ`F$a)LLnNwH~X<%V>dA zmSiI@SJ7qScwDME(*&d34i=gltIN~6(uvrjAT=QokjEP^RtUX@X)-M73Ah0O=u4Mh z3p#m|%dg_t2xU96wB)$#3`<`9x{26Syo-mY@z(+?SuO-elVR9u@DdR$vk-ncrteLU~tHf5~D z-~9UOuquveD6kQW&rC#q4bk3|22IN1((us7ne_M*ePK;UVx~z?Li;zdPv<6JpX#VQ z4?E;K`aw_E;sf!;^@jpc$FfhE&L5@F)BIO$!Q}c%^`mmB#&uY4$9X(o#^_n5dJK@C z%N0~OwytO+`m+;oI@)Rxkm`|Q#7~%h*#V|Rvv+cwDaoLx^z=-~r_!#vsV$(k!2eha zl>Ggd?GvPT&?UTY(tP#C1iTRGy-Dfly=27e1n;IqdZ8)rNqT3ZtLN{lt^ECicM*Ck zdVigi_dk&LpW*#f@$o!){|Jst{hZYAx)ULZ?MDc`yT6A}Ka&f@`z^#2WU$0}Suu*%D$Vle+B#9aXiHs&-*}n|IeiKaTb&y)oqB} z2jZ$wBq+v;!Qp@&1a+U-|BdI!x`qe;`N z&$tb(_tyQiU39WH`Xa8^e|-9t>;A7C(k2|#Zu5By55PLE|08bVw)Ct+362LQ|K7jb z>;a5@%k?gcV%KZ7hIzIh-mB`By4sf*>w?B|(4>y9VRv#~!D1KtFL&1)dJzm%2G=|G zy>L5a)H5T8-ZsDU!i>)S8Qa12*-g@hz0zp(%XOE|%3AwL`*6l?N%^>1UPx|vt3gJM z+l}9zaRdXkXk37UX8MWj*K5{u`R%Osxo?t(EE&((TCQKR&{)`daEH{*znz&s>e}{m zjGgEDtW@{Gsn573pMCaLbkgy+_MmS?pYNb)*kt;1hPl-@EHZ|@8c?-PXU0;w{?gHJ zCdMVzydB-=$2WGxXPshf3)jC`tC!E5mJJuQo09!`+VoczVw{Bs(?Rp|q1qG1+Sk$4 zsQH@LxsDM}FqX;nXD)oVy>sy9Wgo0;)^=U^d=q1Da(#Ay^D|H8cAKLzbD#%f2Ci@VNpQ`MP9NWD8nW-4W#DJC8QaM9&cVk9 zg}soO-MwJbv;8}MzZm0LJXa2y5jA?7p5K)^;y@4g_iHC;QWzV{^(*Vyf4uz3y_;@c zO3^&|)M@-aw{ZP?S)IN}+nM|M*-tOzr#!Y}HDk3v95`sYuIgDM{i}o)KlzTz8=v{Z z%XlYn{r=C=F8{RW!f5|*u5Nwj=^t6f*WR*Efz! zJ@n!8lWw*i(S6O-@2*Z`Y$OJ44jP}@*X9qK;HzukICAg4v`1<%_72xy3R^O9&GFk2 zx8FS8G9|MSuC;x2O27Gqn_(OK%{%$R`h^ZoY(L6P;rfGi(YIRIr$?AiYi_T9-10tS z1zbP2@8rfy8@v#?@R>F@du{&eL$ou>aL~99YI?oP^fT8AW_kV;U4I3h&qS{Gb9|w4 zt#m9E=z30O18(T*`{kvs+m3Qzvy~_2E*Iv;lVEwX{BhJ)b zzQ^%>T(1XS91fb>C+w5Py)t@R<6Cl$9AlHX{#%2$wds}DUb*QsD}G;o4?SZa zbN%SvPd@)2#~X>;I`(UFWcAL$jP<~8)j{*-*$e&F|7L&a`3tM-{kna~%NPrC{khLR z?5uHK(_qS?QO``Mn*BK58(cpnDsAbx8%aOf4V}4i)4Fgx`#oz@K2F)MUG3WPUBAYO z6EA)_zoQZL;riU%g22Jw?JHb&>D>>ith*Y>*h#Mc^TLTS+pAnUG5+aMqw2Q!8uf2k zhw`!Jy*n#z<+Shix5@LU6=nSsV`;9RRO3Qwe7~+8I(PjgDe^V1cNyEm^--4wyn3ec zLeGK2!k%sV{c|mFAL~*+A>(4ET`3HEwEKa6?xA=lX6VZuC3n=wpAFX*>SfAa)6!Puv3sjcaQ3=~ZjOwEOBa{fyG(&h0j zb60jAeIlN*5d1bAG(%gho!8#2>ab(mjZ5BssqP1iJ7;f{c8AcW8>_;>wtQ4{nwLc z9BfcM>gR9Ytn0XbVc1;8Hgo;bANKpCePHUfxP6N**_-y>Ks~wM{n=GVs)>Y!glKGz2}+*@bE!m2L@91F+}TEti+*N=;8`ofMr z+Qz1HtlKNQmW^U;1=q*z`ex|tZ@jv1S%3bv&z{rk8T*p!`&C{u>Ba<8`l~;;Z2o-O zr<>6Zk5K+|KCWKx^~cou z)Qvl8ce~k9#@2BCk3ZKP@%0$bfH}=KrFh3a4&7OcTtsQ))4QLzQJ`}&*H@V*G6zkP= z&L{JlEU<4fYf|i6;3pbWKJjsz_SgQpz&`G`^nKGWKa2MC<@)^mmCtB$>J}WH>(RBB zb?^$t=5u|l%NJWm8MCi`UTfB^PY=(<^LCQ!M-5r~Qh2-Vm8{WU?U+37Xewh)O(_5Q zjgyW%9oDk3N4?6chQ;n1fw3Idvs3$i-FDE}aZ>iN{V!eGifi4>^?`{~mad$#$8qKE zH!rMOa()PS7_Lv=(e%@Zb!|Miw+;;p{C;g5V||-a{*jlz9k;hf=8S?XKWuLj++jAJ zE3R*{wxzmhCxj$KwY(#UHo7HkGmWxZbYrqR(m{cJln9YtJ?V z4}`D9?;Vrd4w|pGzICEYE7N16R~B|SQaySgW8qw{%ghO@aw1^xZ)(yb{M+A`Gd8+8<-a+4>6$aQ zCf@XUW!bkQzFW|VvFEuy+<3lV{6O7-mTpZ(b}?G#G4=!3PrMesY~W|rmgT(e9=B;i zYdoK>c*i+t-e_CUIBv!J{n}Sfsh#)7@3@cSx!z;ek!_i)7UhQj+3@6{uRdyv=ZEWk zj%nvlXuhsTqxXLPt*=MsG(0~oDW6KaE@gjHolV}e!@b7%p5s1dER5?XulDNuTH2bb zuW#ypG4RaApYeO-`p-HH8P#U_fd-4GwqN|=d9Pa-r*Zw~&a1c2+B`dKZS1<;kH+_~ zGUleG{0nweS$m;JaXu>y7&1H8QaVC1Llu@ z&TI6%KO8eE1$ADN`4-+A_{}(Ix}P#Ruit%O_Lw0lmDbofzJqZZ*H8JVWB$}HHVuE| zd-g|LdN+qN6OVqnYly?=V|{PX+U^v&E|)AfhGQ?{a>Qu>WAOx!uG z=kg|}KYa7*@xyrk)Wlf9LG$GPrk5OC*0p%{*KWTA>|6W|I3unf+5Mv?PyD>5r?*Gv zcJJszpxepyyK{H0=u>;srM8|e*x*g4HZc6~D4)7t%r>q~y*Qt3uX*wOxTtuHpSk{z zi4MbFH4ZbbY8SsWAoeHpn@@24v=jTse(_?%dSO{@f1l-Y7QdCFTz_foJELRb+HP9W zx>1YNKQ=8T@4w~;bwS8})e)g#Txtn&JJ603rj^z5vTegKR@$Pnc`3rlFnBv=e zVtmf^SDIWs=DKqFYR@;nzO>eIwm<6Gj`B$gy)k#+@(thDNOAn*)l;qTo*B&b>xaj; z${#qTPVke5t5*8t=Svt@aQ$NoPkOtYaJzN-)XYokJ-$TW`w`dgeCzg%787Rtwk&n| zie~Fiyo~Wld&)of!lN_u?8gQSYI-R0`MF)(8Jo!UqdT3e_Tl*hZyy=`^6`GZgnuQIk8LL0hKs|JXlskH{s1&Cn~>k34741SeU#SGQ5;xfQVGOIVRCvY&Z z7jP(W5D-Hj)*BcJ>1qO>18RXU0?{mVomSMD@1qQUd{aeLX@Kv&>9KsVsKK(sa63rqyQ4;%wL0L%p* z1tKr@5zr3x`4m_U_!-avNXNB6I=?OOOQ0L@E1-wGPdqd2)Ae~mLLpFbJD0AnWILg* zRy=0(li~LPb>{V>=gJ5A&Opki5F&B05=Tq;|;r|6#ysz_~y?Th`@3O1BC)3z!R>4a@@~jrC>V0^kYYVj$XrAO9M-4EuN`GUQ?X z9r!fxCU7ONIW8J`T8T@h{OLOIys=yewa1STx{i849OqjXq^p9zdH~&l9>7E({XQlD z>Gv=d=mne!L>uwng+CB=p=Z&$0*E%}*Aow1hkZTp4WI#d2$&4SJtm&XihImVz;nPX z;P=36Ak|k3k$D(a3xCsdPIYepp$&DjE~|{|g6xM}glKUA{UEWB`H+o}LdaRj4M^vz zm}i0HKvqKzLasv`s^J*K2a*C=1j&c&hn#|3f;d!1KM#q9ft-R| zhtz6>@*)0^SjY@W9^@e8G^7%Kv|30nNGxOqBp0$9auHIki8THW1SUgPKnfryAeSIF zAx=$k4Uia!1+oHC0676+kK!62(U2LCe8_&tMTkQ)oCk@3SRivC`4Ae<9)z5RT!&O^ zj_ZUtL;69YA!(5Lkd2T+$O*_<$PGv}j58ZRoFV-n5fD8j3$h533n_r?ft-X~gxr8Q zw8XVQ+#&vuXh;fV4ur;>8zF^|BaqXOOOTt823nj4afkRoA|T0-9LRjgM#vt>Daa)V zYlU+l&Ja%sjUSUCS&%u96_6c}{g8{08<1+Pksd;0#6U<4Bn`3%k`LJdIS4rgxdN%w z24z5;ApIbLkQB&#$ZAMFWH;ml2H{=N9BIG8d zR$JT~NN0#ABoq=0NrOf;kX{gfNHioFk_DLo$%Pa^PD8Fhm^1D##1#?JX^{DljgXU&n~=sGktamm)D}=%;QqHjB@{8{{`&tIQqAev zk_XVe`2Z>Y4o5UnyCeXrKy;8*=;K|ngZaQzL#hrwIPh}NrKOuKaLO^7O>_qNJ5-}T zN{Zx5BSKgml zVxQ&;6(5>8bWzwabm1F@IBXrx@vO|p!PHKPMw4EbZb;NoTbA|_lFs7)7PSw}`@%=a zEY(%=sj0^d+<8XvSF+#~b6SE~Z;;xQuD?D*DL|S(rW`3vx*;XbVjPcD(wwS??9bwC zPa4z{f=eTNn!Sj6GhS~Ere$?0<~Y5M=AWVE^~TVqyp7jesTZ}kbZ4b{(fF_tpXH_f znvQ32ubzMo4a3{LzSK@EAG(t5dQh%kFiOO*mIXrABTcMSzoK@+Aj zx$R2zrRUB9NvG!+NIE)CeinJY^t@7L|^b$KYCNqkB#ps>e3spVQJcQ5*7m zFRCLyN&2U#j?`X`a(mT7*;JQ$G%L<)Befx&LUp3w2DMoqdEWZ8T%S%jMt>5%g8a6W zs*mK)CAo~1ejZEwb_I2ko-L}E;ul7BP~IE4D2p~H30NE87Sw?rGQ3hsw}~zhnNZTw z^&p+R{q1@v&mgr;$$Luq+<8xne;-O4UPqcExcGHI2hIQgoce>BI~UD)i{`dPbJe!a zJ=;2Gyt6aimxVVH&gLJRd8nQ9(djGfGhVv?bHk!JTG3prt#hch&WWmXoDX)6v!doQ zZJmSsr_3pe<_JY|e(K!bzk6;k4g&zp{r_X<@E*3gI?SRm;qkdGbi3>o?0W;Z0R4fl0;7TN0AqlKK(Y^MpUMk` zcuHeVZWmE`RiX2N&}Kk7!bBjAQ&B%YcQp<%RRhxAH0v2r=V(3dVJ z8|mz!pA4)9d>jaBn(u3YQ?cI%I1@o}#Yj)M z1lRz$6sVjhkLmdszw~*tkq%k$xhb;Q=E>*LeUZoEybL<8JWU`k5NG$myCrJGZIO-V+Rfpb>1P{uaA=+XxBrGZ3$G2#~7 zWX@`bTqk-*(nfvW666=k>%?e3gbDwOIt*kJKBS&Wu!uh0ND z94b>!>dWMf-!m$gbakmdR34GM5pnTYqF8jlETyiYWSiy5H)<&Ipg#j3E0GsYW*4=!4VA@UQq)$iL@j!Cp`Aj*Z>Gi<@s zr222TEL`_g>PuH@K9?u<_qUb15&8d${F+7n$RdA#Tm6(pe(@r|W060*$e&l_|10v_ z75Vv!{MkkRyduAKk-xdfk5c4ME%Ij+`C0qnckiGnyS_@~XD#A5MC+pVYAOG+{<+Z@ zOgm`G`r(TF&7W^h>C5^%+v?X`QU1$r{JP5eDU1A$MeDS3c{`N#I~J|qswjVC(K;~E zx*uEph%2EJb|`1vn5}-qwyq}=aTcQWWP{sLJKjn8Y z0C3QhU4KTy9ufDk2*;!`t2CA+n-?y0WQ+4H6}Bw>fpL}ja@K5$6#m0qOdZfpnfHL>hBSV^KPf#(M4$+AzklQa(d~RDX=UIENAlq%ms{P{~Ic z7jmC!&OMaOCj{weKNLuuP#CZ~FdRtZ$_OCklLnE-bG$5`Pfe)wq{kM8bX1?=Kn$x$ z&;4&>fK9MJ3P@vW(!-^V{0z9?bu6$m_Tz!xzyu(TA1Pf5a1IXUK?)(KAlD%cFg|dG zctT+i@CCg@p(1}S2OECb~T*PNvExKynlVhv?zowIs* zbciXAb#`a$qi(KUTw|iVW8#gbm=vRFEUw5vHfJwKyzZE;lqK5~dU{9d%CHjBIrRR~ zaSL6sHYGjX7fG+M2IOne%aPuDl3uasp-?xq1^&wxpyw<~{{1KRiP7t0#v@vUIVB?| zA>E>jPtnJO`v&^yqI-FeA|@>zQNE1OO8-*K~xDIAZGDRy(wXlQ~hIIHv#-$q#8C~%EO*dF@CGlpnh5t~E-Ejfl zfn9u~eOW@Pp1CAwT}64DJ~biqFvkZk-hSPu!qAHM!j`T8UA;8fBF(m&x^ z7e9TOYT4FST@s|gW?j1;pl_6Kpe`sNJjg4;+aJk>2LyL_gW4-t=M{|n z@CThNsqwE*$nfy~u30@?(R@C^Ar#y^z}r_k(Wko`{_qP8=}!lJe51O#N(Z=}o+ceX zLbrwg5gdV_+e+d<{zq|1!4W9ORVql<2KbW7!?nAVEmH7WMCby7!;uIOvy1o{MddHYjja$Wzhh#*9&!wJC=K0X0D1ZWS(Nm79n=8p2xh5HAD zQWD-&qzLvMt_$}W%Cijd^9%3}@CuZ2=7kUPjqu`s_(fBWy3nwID6a^#Gm6%QM}+nF z@xi_5>EVIABKdvs4UR%Ac_~hQ|1j{VMyeA|9~4Gm?RDWJg1vR#A(0f=To>gP7>Nd; ziUjd1_Y2VL&JCZ03VQW87y5{D%v3KNqN9$`{Mke%`KoJvl z7XCM89KsXKX$HJ#NA}dZ495?Ag5KS&C*CK(-X3`9IpXIICB$`)_zO&ciQf zWLhu0sr?|?S{J?BNMk3hOS0L*BRFYYg78A5w`DZTNKc@i<8OC+sm2UEOVpVZ_jU;k zFL9f4DW~%+*&$F@-hx$iT!*;;JLZj7wER}W8+{1vxzQN0n&Xc+9_SS|7@xPmYhkc2 z>|n0H1$|_x1IpZ4ty+{jH~jr>KAH!ib6%0oK_JQa6k`VZX+MmwF;1>0pVJD2 zgNC()U$Q;w?8WCkYVmxgYof5)b}w7Q^P}oEM1KF_`Qb4|Tq}!Q11gV37F3=+1~T}T zgfWBPVne!|lIPJt&V$zZVI{9I1wS#GGNL`YhI+sWyzEB2tSZzVj6a6*jFMDuYOjVo zUAATyn2mZUw>2eY5$V~1hVh0JDIJv;&(pbR(pV*)ra)?>lO!jcCpe*GCNw!Jd@$up&#-Tq zC%Aadlb*>tpGf-MO7nR1JeGYLseNnmd#*+PC7%X5kM1Yk|FU;qDwEou?px`*MtM>@ zQX7|SVak)*jM}v58jD(#p1n9BTGKjH5T;Kij!0z*dF7z4iXSg}r?fE|uXNc?jR+=~de4@)q_aDNR&RlL<1^*^+ zR1TU)dK`WJ#~y!dUi#dx-3shyybcbL>q9@SyJfIB?U_%PS$Cx$NInCOlItxo4KF_x zsM+H3hV#ltuZC^K{4&>Xoe+PT%W0(erCdmnG4q}X?oGL z_~$Rdk-1X2AHP)KUVV7drXG)Gjv+un$W#N(k^Tndvg)|!n#pCf41~EcffvI^@Yg^ zFBB|zwF>SR*FX8&BVT5v#h$M;dj85^4xYt2-^pBGHV)hxt{*t}h$c${xQM2hB%^gMwqa{pX^``Utn7 zOPe16Y3o@hS&RcG_{RJ^BxV~(hs(7wH(>wLT^B>mv_MqFn#^(!AdnI5l`H=8N`^Hh#Qu1h`SI-&niS ziX*oVMa54(`(=cS;|Run<@&PoO-=FZcF>fKm(z#q%f`it=lZhoZ{~A-+4-Z_xV~)M znv+~#cAn@q*O!eq)54wVnd5S^#?FHi>u)HCdT!5zgb>78;rgu^gWsK1(6h#*KaQMV zQBW5?Y4KcN|NXtz?zex{y%=K5iHpiaXFHGU%f@Ybnd=Warsq|5477gX?^E?F$1Xo( z-7wdm`Ru!2x}Itg+q7f#IU3VJ5c!w5{)svcJx{#b_S;%#r@ir-&!w@r?>(rVH~r?n z>VLIhz_Sx$wms+aX(Tv&t~btl>N~ftBj%6m)B3=%(5iUerg42VyXcZU)_V2X5xXb1 z{pNX)=-atIA-7v$!sk(EzX;sc!|CARZI~bMp#10f+WA=WF4S+nlUvdgAF1_PmL;+FTzJccs(k)%qttlA1m>@z$5= zh-<<1@BLI~>3WaQ{>^7vwtRGO?PB<2_N022ji=~@@zW0cwogLHY10W32#JMcLFPa< zLTD{Lt)r*k<0%NOr>FJvH}H2gJj;zCu8=?ot(n&Y=Rj6NHbPEm!T$qUEBtnWHy{pp zwzLpeNGL=Pp^1=Xkd2T+2(4Q`1*CQBmuMgNxgR7MLP0w6AO#Rwn|=fsioWlCiPjAd31kHIPYa+rnE ztEC+h!ugHO7=xQtX@N5$_i1;2mVXx^1J!a)xB{f(jVGt&hJ4%P*mEyl#`ZhU;z z6l2kY@-co;86@KOtgKT!DCdcvEZ+zz&$-HZaq%YZn5TmwlM2#P9#7NwOP+R0IjrS+W z$5JwNdNX`DmHX9<9!hL@#qy1i%6d&sUwpr$Ix6Qy$mhubyGT0kM2YjfLXz^XFo)nWxQ^b+`^C8*a~ZDb`!eY0@=s zkacku>6)*jyevp^FY3G4^r(T3pIp1TFy^gF$NuwlGR9n7-}vPXQ3daxbh~lnh4~%g zKHkdM8Lt28jUzYSzwG#3^yS&T(_ASSS946RJ80(iUNC>ytA(?FzT&^7QKf?@JCf`B z|MBag7ayy+ZqD16zOd#mz>7tTva2C4CrBV91u`G95poc65u$Et3#cvd;98)f`+sHf zkG}Oo@5p~y|L@*K9stn$x*qHu>f@C@M(Mxj%l$X`5Ya|Reau!Vy{FFC-(4rUen;|N z*v*r_38_z1@=#)&5a&o6A>}cxWFFMv6w{eJ6Uu}7n7vXusaNEjPjO%EB=@(Ac+T7p zjOV>*q1+6aRig5#0fC&Q48fE}i! zF{x=qxhgR(S|hDbW@>6Su;ln(|P8-Z^}6=jST*sU~;QrQ7a6$+iom zi>`4NcXkbzHMM40`hY475DNd2xW&OqU(AQ|{@aay{}nX< zkK2qmHYrKUD*){AfBz16@u9Q%gmfa zw^@GHYi&g!9?lRr0`u~vgjq3lS`u`NUjwrq-s{fDT zAEf&KJQV&vQdl|31E{#ayAK{f3h%g)2xV;c@)(hD7;LL+dKySe@~@zApp>>wiQ~kAOUKF2q2zHoPb0?@r1LR^Ejlhh`a00lLo>H2+6~|5RlH zkZgZ->|gFWiIT3K>eyc$`}?TA|EljlRuibc{|~qCf61}G+}GWQfj|1=iXP*|@-d#> zCriTJzGLkw4^KPO;;MTAzBhuh$mc#5LjKerK;!=kn*WpdkPL&Rqz|BK z1E@BDy8c&P|0`HTD_AS5^8ZCsA?o^HtnYnj*8i5Y0gC&(`(Oqr{QrKL|9?XsmJo)6 z|GyZ22me3OkZuNFTt5FVrLD`46PK)EScM8CexGcBvd4*SmW~tutQ`M4{Qr1NEO4H` z6#xG#uWwoYzn79;=Kre|?Ms|_hO%FR{|{4irTBk;MKAOJ$;y5y{y+8(eKG%ER2EM! z7l`Ypxq;L>&bf1LV4-rX)ZD;aMPFiWV6~zvH8-$K(cfimfbJjNz5kE7fjZ#-9W>XT zI``b8Z*E_{V)N^>s&@;$D9sIos&fOl6aV~;#{Wb9{`wzGOO+S;C(dHdDvs~XV*fjz zpLu@~^T(WFk=$q=)@VPaTLxbfOGvfY5Z|YC269v-3i6_c_8|u$HMCFBpimhf^N?I6 zej4Q^C>x{)PnwkQUPIa_)ll7Z9#S`*^4}>%Pl;?>{Pz)hj1NtO9=cNA3;pe}cHN6JFU=phDHuYJTFRL&C!JPp%I}vZvOcZZmDNmo@fBAPwyGG8r9G?7v=e0kVGWIUluTS`9(uld2rtf?_?YTLj z$7`d$T>sdF4!WV$e|tOPw?9q>)t(uPFhTvOo}W9f-ac#d?69@5>vlgH-@_{QM;Xl1 zmyHWDf$Pi01$mk4w;D~FUVX-GXuY@Yr|qJXy&2of_1|x5``$wR>{0!5H|;ogtmX!+ ziQxK%O{PC*m|K0rB4gOA0afdCMmuo*9}^vhy=ok0T-7dqX+Z2x=dkvoKd*nIEQi;J z{i#{fJUymU<{V$d9_ISU%ioUM+aq&E!IdAjHwo@A8{dNEdb_%dKC6A$$@7b@J=+XC z5WZF%ci~B%zHEGvH@QA5)qQa4Gp@;JpS=~Gbo{M7h+o3>Z+9IqBp~OlN{ya2Lm zXZ)e_j2XH9)0`&W1xuo4cW&vW8~sTv#{9Fmeq2=37k2c~Ha4AO-K1|FuH*W@9|z?q zPj620Jlo3kK^}- zHbQ)wGVv!uxV~)si5#vk8-HRC*MI+`pEdH<&X*=;?cU?nZqyXUzTx_^-^b8+Qn`VN zQS(1@>{jrSF@5`PoH`jpX{}hnf%iN!Q@TH%y-dwV8KnA!0#r{lJW^-S@9`?KJea zsZZrDo}k0pAg-TwV*l7LUTjz|EUWGBvs}(LW$Y8K?>K*Fti$wiAO1Y6pyjSz%|FEY zbT6vU_TklAjh*>PkHdC{_O5bT-IB46Tz_@=3GY>@zMCus(Vscxy@mK6k8yq3xF8QI z{z@8y6Cs`zimyTOG?X|RDR^H|+>H6ao4`|ATqoYCD_S9z1;iN(&2~U24n{tN<~?^n zD82>7w4hiPGuk5-2E^4_ieGUASoD!0{Hbng3;f$!pknO*EQ>iVgA)Mv;`gW8|K+R{ zQtf{=wC`Vs_EqhFHB7G{TzhF7SK<`^t@gjv3snpOa6jz-w95DvPk$PJm$eT?ynx7V z6s`ZT)!r7_^CG+Je%t3F`%`3R+G@AkYHy495s|$;kK0R?3U3au`_*;cZL;DvPWH}= zXd>p7L_CFv?|4xBg@_*%@l7JWLlloRinrUSi5ot8s$=Z_G}oiIZ@=3$QOu8s_zn?o zGLz>Y_5DqAPSb zUeEtT3y}REe9!a$dUHlSsD=!&VF=7XF)&Yv74^~}W*Qjb;)w4A^#}3Ttrl+TgBT*RQ6;4W!VmRerUtABx=M% z{IlsO+sN~qN=0LIh0<|M`Q}i`dsg%fBc8rm(Y-2tFKDbMZ-03&$XA8F0VA@>MYgwy zgAj2IqHlGGxF=h=2@%&I;@U)9Lq%~4_nWh`m75d!!ia2dTYYV8<>o}(frv8|aig|! zd?JoR#PNx~1@fSLYD8R>h=UVxB_giMR!&O9ZQXBQn;386=Bgh#K5$#oCo6x_%vp2d z>AVJFj!DENiF{#1T<0~sFUc=O>Tjifcne;(=;As51Yi@;B~#x#2}rN|93b^Iv=91_ z%>;saVzYowz$bukNnw+LF7kd?AY9U{p7K7G8w!#7MuzXSF-GN91^Pf}YouXT!p1-< zzX_1Kx~9N7z?Q(ez-B<|YiVD}SL*x9&llglu_8HZ3#5G80V&`1K+3lhkn-&Sqi0w30uN!t)WwcM0d;_#0dw>o4{TYK&w3AQ6x>h`OmQ@K0+2`t8{e|Ev57<(LEn zqBke#jHziU^5Xw{@dH|-t^?xVSij@z>Z%`*!X&EefQlSAlm$5IIw19P-3b={3G{M5 z*IoW=yXZ0cm#qUT*&9^|5r{tWZd{1gdg@ktg80yM;5 zf+4h|rt!3nICg@kt;P3g41bRA*XHLE$w%i>tXkA|ys}ze;o)B3X@gjMFp78Mp_Dkd zRA0I>;s~j3v@g}3cu6@HF3KyeDP31@$8EeUtdT&w5vND|)nEBqiPmI@_=JI;WLK75 zt0CeI=5ssrojFw=(|`5CQI}hd&#Y@at$D?*krMG&B3~|BeX2w}(r$iTvrZ(AJQMxV zyw4q~d@=FJo|&+vxW4|AT}CxA9R2*!klO9`taeA6iFk>MTFYfCzho;fB;rYI<%LB2 zr-)~3=0ne0$Sl9_p1JDLV8F~eiF5MDZN|501#6*1yo89467jkspEFzeUJiaB%ZgH{JmFpO`C|PC4MI#BK2MPRvG@Lc?9Y^Rzqle1YI2Ub8yYF(mTEx zur1IRh^1HPE10zlur<&P*ap}gh-20szz)DZK=4J@0AN>O6cDal);J(&7;7>RKNTyu zBsLJ34s-`*1CfW-3Z(KZz{W_Z@JO!sTj7x+P?1FtT34oUNhSHC(mrDJ-Q>Tsp3EO* zJWN|9ROa6Oe=z7wHWWDk-HYwNK(+l<+g}&p+ut?I)x)(rSdZZW!NC!#?XRu@q5uym zsflvz61_e~VLw#cU$y;-0V9?}>4_e8yFXdB`!NpT^K~$x*j(7JZ)qjFKUHGXaXFH& z3)#XNmJkoP!^T(aZ_<;EPv3+*s-?7DxqXgt6t>}UMoWY-)gYxI+x~kkrKycH5-+fi z@AqL&(3Q5=<*MQ=Ci{(4c9haHnEmNAtU}o}`L~9so>WV+%fHf68Hkl3+vN)9v5Y1P zu?0eCu5t)uKGN7@K92mAWX_}XwVN~XAsrFFL3$cbDlrg=lfZ6Kn>@<%?)H~$(vznt zZj)Mk--~tnn{6VcFK!dX*NL|YuRV>0%W@mkR-JfRW!q{uO%`JdhEQ8kn=L?Fh4A!K z@d5eb2SvGd4Sb?#%=_QAm4WBo<1gE4CQnn`R?&Rlo4NeWwvy5px0Ukz(DO{S7qwG1 zFQ>Sji0fH_b3~kuh`SNl%p%+PLD|3}pCOTNlW6^)h%*w|(xUi073B*h;;Ka4(}UuS zM7FN#lQgpP#6-qK+=_@p`KNOwTYZR|vtKmi((RcO1Ntn{eZ6Gi=DlLBj(GaO$ z=ez?;#`}u;RC<@wM%)Iy+ns^bHFgFz0K)Ibss(}%;hYC?9pE$Iv&yVAUH~t`eQGFw zsqd8XES;OdH#p@daL>l-TFe_a67Qm~h0^ONoi{ zj^I8j_}E=a$xr^t{wL$<6L`h+-W^(%`=bW*Hk%TSNihK>T1g>6!IqR8>G_VA(!V?Y z5ATI4i1@2$f1i%>`Zi}8_+z6v%*v2nkT*cc&F5>krqU&F-i3G&@Hm6uRy!6+intu^ zuR{u!Zm>w7@!%X6aeDbYkFsmDuUm|XI2aLUBjQ?Y zLRcoV6Qkopc!bRJcp!!jnmIfF}~{)9LqT6abq5qxVnN2CRk-wX9M zc%^f{7lm`Vo6k!QPOb>Qmy0U@g4TcdHX0k;yZ;Y4{}@e1`OBZG|4)pxbVua?R1P3A zEMicg555GVQ#k;Y0~lK#!x3Pz7}9y$gnOG)Q_ZG341AdeDN3Yr04aYF>8PkDdPsQy z#RujDO_*V8ApvU+Tm>WkLr=2%tvb369d)TZ&0ojVAzS?ueja1XWm{b-r=QF>(0n3o z^&x|>c;}L5iE{Ax(R!lNem_tt8|MwEoNJzR9(*oJZ~`Cl`s=Uw@5L=$lfqP1+IwNCfjze5ybN3@p8R_;Q?Q8@Zi zy9Ez-IeW0vM_Ft44ml9JsX>JJyI3ObLd125*7%T(?+TIL|5CrOAI6zIbWRZ3$i^q^ z45a=7wtrDf73qBr{|V^nJp5l2Q)QTZ9{F3;f*zN{W6wkabFfbwfWimdK*ptgFqHK# zIa=GefE-Wpca;|5*hYxDJ=hkY=j7h)f5}@}4*j9V|JAGZKcD(Hc316x)&7r9F($yG zRcu_<2cUG^jpDXZ?SGeKvn4Igl8~%*35w9VM0jgmq8S$Uu*5zwC6;^%y&dG9s6wp& ziuM6eV%#b|0L#$#(j3kb2(A68*_&+ZsnR7tS6&Pc8s9bG>E;&s1Sso1$R{9!pC_#Y zistED%GmWZ29&ou`~hGd6vf*hTR)Vae`j2cIk5F@wS7fn_Boz3*8cn7G!@ybBHL7C zbBkp+#JR$c7ei3?ds^WUGm|f%|Q9+d9uLTH_(I)zq~gl8tVwEiST^@AtgD z$iGI!4Tx;z2el@|o7?)!18+o5Svn@C)mRs{$9?l`#H8?{_fpyTDUp4}W zbs20l5XTsnYFcA}Mqm;UJg^miGd(a3H~|P@*}%y_GjIkF$E*v1ZHH7xuXpB|Ou@ySc(8%H85n(i6Q_azY^q~=UG%qijXaA?z@FI@sVYA^yT!YB=7WpHIYy4qQ%e zU1|E)wz?}yfT--(})<%I&(?O)phWdGm${J$K9ssg_Kp~n9#Ng_z=bz{_Te<+az)Ng+j zO&*t6_#Km`e*ahf{_kIS#g~1j6g@^VJzA;opP1}9DU0LYhd2MrTw^Z(xYq-l9m?4CaJ+_zCT zhB;{Q%?ZxAdCWSpEpyeP-0(jeo;>u`M{QvT^WV#~6Z^-0@nXYzVOec|pXG8Ew!Fyi zN92bj@^29N1Bv{WMBHFSae$&V2)B9r^#19+^Uv>Z(>HT>P1hg#PT7h+2`~Nq5UFpH z`l?QyCJk;+Mjb56g!gQ5BLBZ0MS2LsXrPFBu*m$2%dvtK3lPlf%_YP-{7$z z!Ef-j38)75SHL;kPXS#bPd6Gk4Cf^P$&Xi0kN>i0j??|<+h z0qXkyzgqvFZjgJT3L*e1+Wx``=Cd{%0gUfJ$B;L7e&U3(%|f zze%J}WH>(RBBb?^!?pC$6iaOd{?FMd9U{@m&I+^JjVkM!)7hlSM-+d3K1 zT)1d%TQrBQhZR)bysK(+Ka}R7TB(0|3y}SP@9X~)Qp_3Z`u{sVwWY5ASJ(fm>;KjD z|LXdGX$`>tgYUo83ssEaU(xga9`g79JY`4v)#!I?K%RlvIWqR@cxnAVzXqMjtgQK` z*nZ@%s9}l80Qk#G{{3(8^p>I+faKTTni4R*IYa(5U_GQIzy3!Mz)6EIK-uBHyZQCk zVUk}zl}RO%f4)6GUyAup`?ckL<-34NY=afmseH!vKxnN2AzfP#Pd`=1uMN7=*F^Pf z0DTNk_ZoW+XIEi9j?`2&ncC@ zPpNGvzaFG3+nzNY=^Chg(;*Gf-c)beFTR@M?=4b1ulpS{|3Ps%iQM*`uw%~27dLeH zPu}~3MqjA+C*mJ0;rg$mTOK&|>HBq>zw!9g+fNRMPq&CO5OGwtaz!GW`(cYYAmR=y zDi(ogea%0ebLt2mYzNKN;U~OTrTT8N6hwdKl=s$HvG0woT$G4&%E9}`L6eZ%tuW#9 zsIy-LZtLN6@bEUq9u(*F4*z|%ja+cF?dr)(-{@0sX_VzyfAKm9(Rv5b`UTN?4bl3G zisF`R<<4nc1I1I2`d-Am!QY`Uh-v+T9zq+fTc`p=j6@zMk>VvLVqXWO4jJjJCLnay zSwQH>eTR(!()t5DUe@J6q_I+8PwNt>+!YY1UzGYuDwq1I`4HMVARYCgF2JrpiUAP` z#NT|qLpNX!_R(ostw3~C*114*I()r@2k%pfc=15fSy1+f($rPp} z8;Hlix(Il35Mx&$ck_+O(IRoHvfqV>XolyhHOgy)Z&x~DJb-mJp^#WeNuQYHBK~|lC=2lU79h)kj~~+>F>xACg{t?d%q*d0ZT}s6!At=T)NSa z(Iu;w2aKMW@d@!}vxU?#^zDfl@4zm;(Y`DpRnJ@!v@T>;C7HD@Ay}6lV#MP0kPJvR z{ur!>gy9cgf2e%@k$7+_=>zGXa4cKb|IGmOCEa&a4p8L)RSr<)096j~|BnNddZG#; z0V|pVRCuyVGEep?`d%926B180H$&zC`87zfI*1nn_lLew&%f=VaAhla+7H_|AsT0^B0_194aMqW}M?99&Kc?4yK31g$*y#xw)3rb#qsA!A0qaVIa<| zvg060mt;2U!K;_psLOMYEt{kuf|W1@A819?7W zWASVSvE-n6_ST53dDfwkpUqlb=dq~G_Kf{gxHHk51aVtCAW~l@^=-*8G8;g*5kgyg za7@(ibpqmV{ykG)AaPv=AaPuHozwSFdAw8Ny0WoPT-Osoci=K0aa_c$5ywT`8eZMj zTp&VwSl0tVUs+!Rf<^r7+u zvq_ErnV|Xr`RJm1dFa&dfBN+F@W2ut)&5uQf7Sl~f3yFUo~S|y0E`9h#sSo0wH&=2 zFuw+a*p8*)Be$urUv2v~h@0#ibg?Q5#MV**l#MYA^3Fp*GsN=L>Ew$uXIjem@yMqT za6cEaabM@>F}A*;t^ggHa@ITqqd<#c9`Xd5Z7Z?eo_x*4n*}Bm_jHN&nKaUysTZw~G-Zwj!;dqYr zPJa*jW|T90JrsWr#n+>>pU2sDjLm?-UjT7+W-JSG1d@k53nA+E|K9?YP~^RT|HEje zp^0q%tMmW*n1J92-@q7k{$HK{SM7h*{#Wh)|3CX*>WM1E{J)#+U)s)B_5(w0`zGiO z*&o2yjxqX^a25OkTKAFs0i@nl_6ML2o8fyuiOD8C{;IV%dqIN07zLwbe*Tm zfM0VZ=mt2Z71aY1^2mqQB~dxA^K$HYy>6mjZ}9z1nquFCghZn*#XvsORJR7e0-k1@ z#$NLx+n}Lyr8Q5|3M9I2Dc$S54qI40M#gk*W1KsX>zp-N>_yg6Q;DC8p(wUwOLm%p zpUdmT(?zk`%oFDhaNLYGs>Z@Cap{)Kv;b2gwN*Xl&9A{7f3N3ts?Gf;3UD2?t_br* zMO&?+zly(yLifRfc2VvQ`6y5uP+O6XT8h^DP<~W?$B`GwjN+owemt);=FPwX z(f$f~|26seC3*jKdH+_a^qpZWfRSZ>z*fNB#WzSH#5*PN z^j4kG%xSGMoKrRFH2SxQbDAfYv0E;KxFCvmE3)M)$_5v4N+NDVWV74K?TBoA5$B`Y z{$btfW3j};7T3ns@12Tlc~QI@k$;A_FL4OV18+o5Svn@C)mRs{$9?l`*wUWm`&9(^ zll~|6jcMPLe-8TLtaImGV|va&zu`st?Zd0L8awlo9*6A??Oo-x8bq>)3l(vFwsN5& z&Q|1K5(2+62Te4)=#o6vdiB{6yC=8(=J{sgHCVR#XV}V}ioT(g&D(kYZnvv#HZ1RW zaPOv9Tj;KR@$c}@xQI?c8e2$XjV*ZTqw8U(sI$O^zR*hJkcq(hz^On`H*7i(>yX%7 zAh{-By_3}s2%ijVDDX)j^&ty^BY=y6qkv0*vB0IkNx)UWMZjDjj-lsf))l~)fX@K& zEi`LBa2t^PH+BN|0QUh80N)3G0^AGy3<#a|OW+~kH$eDwSkD8G0)GJ>16ISeQGWG- zjWL<>2=Hy}KMMR5*b0bqtV4hofun)n0u8|LfT_SAfHQzU0%rs1yrsb3fKLJc0OkU3 z0XG7>pq#BhJK%O;72tWGBk&rq9`FVbb+Y~mYyi|?>__!$0Bj0u1Z)Ou0&ELx4r~W( z1Eg|YfIYC^8`u*#0EoFLt0%At@EWc^4I=gB{5w00?srY-^bp#HAstjK5=i%bIIu2o z6c9g6rUSMH#sWLYdU{^aHdZfSA`q`Jem*@1M(l3^Dx9LLAO42Wda^mlP~jI#$9zh` z`$~^=#4p;qrYx;(@w&1cwg?a%X}Zd2I73~jQyitrNqi99ot7Lh5sw_GbPs1Bug9+@iXMBBZ}84;%y!_9}E$1BjS0~IK@fF z-`d02zco&=XdRTTz8SXiIU*iX#FL2l5E1Vo;&Up>x2>fo@iS%Dz1YgD6b4W}*|*2+ zaB1BtwX6TMufjqfg~2T1V|Va!|Nc565r1{RebvaG_J>ICYR2dt9ttC>3J}yc-(ZSb z>Al__*c1p~9BxO$+_aM2+zCkUeA3ScDt7WE*q~%1i|ph7#x5@HgY#GRaHYYhjJo|# zwLrz#|0x*;!&sw-yTkz8OZ*S@`#&WEh@@I{=J+w{_kY#z|Ek~rQNRBq5h&{SfB)+H zzePP!g)jhjU;m@{{DemSJ)a*X4)CRF(lBEt;1LMs*4Vq?4&p5m2cTSs5(>C97ofxe zPUGnliZ}pDS08z4$m0Y^+yMEi6rZ1JN!CmH2C|;!b}*Zhp3e7WKOUZM4esk>PlE(z z&hU>j>B-rL{Bg*q#>&%l1Orivrz=GL5$Vt{K`NS;O+GQiOURc?3E+2Aw3W+CP|RGa zGhGK|MSe6?R}{yj+EX2Ba=#}kQz?;rWb$~O7<&(T+J9BvSK@pqYoKyvpBK#S@fa+G z)czNE`l&jl{h=<=b`%l0*r$qu_G(xvSeQo44R=xDVQjqz6yun#Rf%zY3T;;GFI5~B znDVEXC)A!!JiYXf10Wys>Lp_wA4EF39Tc18NG8?u&KSr0igoUk3#BWeqh$r9b#97o zSMj+$NLOBr4uA81a@{3a9xfEY0A;=L)w?9iqkHMKR z_D{BT!;eMu4J;A2WGjax;?hJuL?T}y5vL`xt^eukibPzFh-;~+SS});9j770ZMgl^ zZh1`To2Gy^2D^rfy29z;L9I`+mD3XW=7_j1(fTJ_IV}-)CE~hl^+l>E?n=a^h4cG9 zbm6$)+^V%Tw!SbvulcC=;4Je`;jTm+zpY$8abV^V` zNk0SF4mboh67zpeQ3Ge1M4X-#oZC(Ky_Co8-DoAPt1B5xIloPD zJmqF>%a5tN2zlPk_k{vX=OSGpMBV;(TY!f4_wN5g&h7A_mmPpq{!d;1r^f$L{eM*d zAH`Eic5c$^$CBSukpq*gF7}NIM;!E2vneLvFA}Nz-(T^6N>5Zl^dHtdRdtL6kz&WZ zL&9`XzG2}3A;G#JuOYMtM#NVBPvM_xRg=aXGzP5=!T6Z_02O3Q{9j_a!Jv~@`4w|_ z68}WpUp=JX&C?Dn;+;zS|Ij#C-UK{bZ%2oToEu{M`88HSOhpG8PP2Tuen$Ka>V+ji zC`NG~o_?w>$$+UTEJBniK_N#rh^G$&M^+#HPsJQr>AE6&Wh=L?v|dfATeBKc(q{p5 zjf7OU=jFQT=;LWRaovY%Ar%l=XW`n-|J$-X3|=^8nL>J%%MDb&e}l$Lq*97nQ0ge(-+tfFiz6$aBH5#6k1@rnc`b)XyH(KX=oPbH{3K z5U;7c-+Z5lcbnr$^&FV7wfp|HuAPSdHub68#S?Ul&BIgcpkb%>{krX-vE!udWBXsa zL~C3{Jm!=ADZT%Ik1kg=ww#c1?&;;dqY`#7_9oY7rMeGJea1EU?6bF`|J^=pw(@$b zhf=#u4EW>8`9X(1jA=I_@|S~uVsb~cw(+0N_lfw~mi##^>%%7EJ#F=EJHXp{`jZQW zUY@YK-&WoA{65Y09jG`SP{cpl>f0t-+xQ^Aw+6nCNn;$&1u}{aO>50){6ibo=~=0N zsR_hukJXmfmem1sUKVhq3t!KqcIHD2l9Mh2X@5%ZXgW+-U1ST`8JT+qY&r?d);Bnv+z!Sj5KuWh9_yLgWNdpk6FXw)X{QB*obAr(J zEz;5Te+Q)N{vMbIEc7qyzj(Jbe&unU6hEva&v`H3j5~!o-GDR(3ET^!ZsHceiehq{;9rys_!2@?r7mFN6`VZ(xh`Xdcc3{T z4$gn=ml}^)?ffRwJ-!Z(k*|w2alX_ZmwEa7D*M}=v7__oSzrtS;OVY;hw^k(hu?X+U6uPG zo$_2FPMmQfYD#NU>A7^|ZMLRzLqu({YL45NcmJr|&d9H1xs)HpNkiKtB;#LYt?LQi zc0-t!RR(|DlwU&w9KX)%GN?p7;=RM5r@WgXZ>b)6mD|d7mF_Rkn&&~b%@qC|go2w^ z${tsAPbTnV-Af!xD=K?5KjvK2F0=T4SNn;q39rvFeos;o>4s2!{867Io+j9SrJSaf zbgjIpmH2k`QArJ=+;oRODV;}c?#FdzyJfH_sg0z2I)PsZ-Ou{Cj($8%3hFn&QOb85 z&sTZAy7S}1`0?`U){GxtY4;Y&p!;>4*FV#e*h|NsDXPnr?{DA!k*C|M`4u%RE-Q_f zMZYb&r{{T^!y2aP4x3r}ZIxH&CQxedC8pwh?yPeSetZPlVSwWar9S`1-nGCtQLNty z?>8+V0)iAMSdcb3H#_s4Io~(ok^F+_ z9gjbK_G~-sqwf`zNYh-_5)=2O6gd-2IW}FNACr_FUTjqEtGFypwwP5wg>xY`zZf@ zAcm8?y_bKt5Ccoz*70v7V!6xPV|})_^WU>)|0Ddp_iPvQ_s&z^YI$2J?r7-%Bc6(X0PA^NSYvjEn8`8W*c5;rAY#kQCmB&O+m2Gd*d2 zm9!b2v`W3YS6YOUuhf&TAEo*Gd!_t}HXYT+wdx0Py;KL)Y1MavC{t@JYF`3znv3!S zx3(O*uiJs=R&9CZ__7z()2cU0r1FD5*nN+_*4Q~)wv`!+X5<<04dP=?*YtaT^>_V# z|JUMGzlN``J^SB`iN>x(T6N)=7D&th-Pp)R`=9yc*T@Ddu5El@?}0Nf-2m^J0ypYK@TapT4g?_NG_`%V1)%pI8f z)60!>{<(C)pCfn9A90iab8Lvlxx zG17T^TnbYL!UCeRFA0JH!X11Ub|G9bn0d>U8)+zKoLo&pvF>!7bv0&D`L zaytNT0d@x73G4-&3+xY^2TTLvopEOY?*ZC?i+~Ow-XZsN;C;Zwz*WH4fvbUU0bc_C z415{*JCMdSVIuOe&Za*w^+p&mHbj@zNc0}l7Gs6AnW9r`>7m%FU5KceZ^Bi-!WYBRcR1hy}wG( zjrh)VW$bON-(&TS*ZM3fVLMi;#4L!;yyuO|4w2@L+K>G-e-y=WC4ZJ<*lvJI(-y4; zv>Ld$8mNP8m+t>lRO$jHDZBq5miXX6Hj(r*0Vv&BrmMt6o4MFo;>>deg`{>5N-lEQ z3T-#r9Qi@ey%%A6jAEu~05lDNrU6J84G{$N52i$}euy(#G!1~J0nju67uEpCEs-iB zfSS?(^lc!u&9Do=!NWep`gv>E2_OJS10dalM+87zK86RdPa3~eczYVt>Wp+)e&&MA z%HeU&>(jhbY5ataqcXiqr11$Czc%#!ah>Fga}s%0)@AHB z^v?ryra6Q5H~4J9td6G(;{Ln&ebkDvVjN1>v$0EN!>`i&^-OHG^j>}0J4c{3=IK*1 z+C92qP*5Akmn{65jZ4PEriD=!pnI*N-Z;yFN8bW5oncSDG40CJMHzE?c8oSn*fa5{n2&sf=kGRW*vz}OJ@M9!!M!?+ z?Rj$^<|g6k&itrd*T<}@^XJJG*X}F(>_OCTIGy+X?`PcgN?woNA3gO_hkQF_(*u_C^(A-~S5^Cji-^7nNgF}}-vJ6hc{^M-rgJreyV ze4TjyyP5^`-~D>mubUjc?d2Er$0m#8X1~D8>9gMv^5mu+b0&?j*Lkp3;A`rQ3yFM` zMB@x1zF#z+<1e2ris2#}7y6dJKOb*uy7TR0KOAb_{foO^{V?J^y#L@50(7n0&RS)? zv*A+o@Dk*jb+b`^^EPp0kazE$^1Q*f{a0FTsiM@6YHHUr*WAuXOhM?~lLO zHmUm@jBE4sTFn>kYx-Vr)Th1scNw-L?ICbsaa8`)4HbJId#d}EHE+gD_^QPp7*7z5 z|A=BXiDCe?OQ!O-&c5a6G5M|PecR3bwWZddAag4C`&rdDN;J+R8g~+nFNtCv5l@9r zyWF;LE{X-y@&YyZu_LD;qe@mM(D z9VPEy0#st2(7fVG+!J4(i8veapC85y8 z%y!C=Yjflj+pHzM$_GS3u&Y;lb zaICga{8xf?8vYn=!J3Lc4Dm=Z#3S?YLP}4d|I&g&<1ErNB^MN-dYkXs{NLLA-`f1& z+Wgv|G zj@(%cUT0O?gX(<%j7jN+glwffQiTRkJq8Hb&TcfkYR!G@uk9@A^NTcJqCR|0_tiyx za)0~AqCU2$&#V@wA>txL9D<0W5OE0p#s?5_3nJTDWFw2>c#3Rfe>n=ZY|oBSWQ$de z1K_W}{|Ii=Z8`A8*aiJo@0uR^^3WH;w!&x=Fz9Mv zAJs{~d^A`U+ifjuv5By^XkOK@ejYncnX{GbH^p9~aeu{DBOA@zHWS)q)te()s#XJ9 z4g7^QppN}tV#RpDWHrYBHT&P2K+xv@(P99AtJ22*F|n&Q{;!SyUwHgqvj64wNFDQE zb^Cv)9Ah&`)&bC%3oV34F~0sM#;8aKV8U&bVpxBg$y{JXL`$>NIoW0|Y!E*T(*}vHzgZsg}Nx5&dg?>|bhy)G_+i*8a!HHh(}vsnx$9K>f~pv3?Dk|6AB` z+~!Ag!{Jt!!BJ)_b~*~J4p*A17#?yZ&>xc@fD|Jw2m5I|hU@j?qUhMcoELDRJj{rj zhM;Vab4t7b`6Ty@qCEBaF%pBi#QgLNDJ;S&mz)=i1?SQT`#f+??ZJla6~a-{;v8Gk8s^ITuRbK*s`7e=P z=W^*8df&iq=!%9nt%-6t8%H0OrplICffsw#YK;m~mfpLBZ`*@5E zP{=%{h6$L3{ZoKrfj0xmx8YXc1mJ8S^6(fOplI9+u}v{IsEwWotN<$9kirZ3`ZajR z&!E^D(}TbR;X;B@(0`+ssV>$W(N#V*bM*X)0qD8i)8{i)6Usm=YV z&Hc&kewxSQud@GnD|BVr|4RH`MuSdRAg|>MVGKGrKV$q|$0~B@7H9|g_GbsuUnREu zoLo$KkYlDDN=)zHc>c!c8Ruu*wx+ovZ^)yv0}xNQACC9lj%42U?v-Y@sb!~%>@$D; z2x@wqJ=Q>Wz)$2t)C9f<5Xk>7#H4)!;ufhhLE)nd1a>|?d;SCM@zvd=`m>LR{M+H&>Q0NMYS9{&%67MMt)e5&LDa4GTs z7HIzeJj8*dW7YKkn*LwY|C=HE*7W}lm!|)}u>QZYB~ph5xG3%aFBnITi%v~RO^$_q z-GI-*l`=XrEj<;n=&|j<{*?3-Q*3lXLQHh*NRuHc!5;5oZIg31;C9ZT1!fD@~tt>@=QMNKC}hd_4cB4YdPl(l(>MT3!wRFM(|_P_?%u! z-q;)j-E}&6j6fQPr@S<`O)AejlFu<#igX<-O`ld|<@sp*g?tVuE+9tZ^`(V{)95cc z-+mlRx`f))kzhr64*XAZ4N>28E-y10G0{UgpK%KJgJ@Bi4ogZ-F_aCoMdv?;GRE<| zG5lJ8l=4lrIZ9kPJdae~wfS^iEpg1y!0&mUQYQ}M*YW*1*I{*(+G##C$tU6%FZ&vP zuA|6j<=X@Jz0RVWV+By_N!Q&9TQ0u8vu+t?#qNf4{lU*=!OcOLF}lQBoSZw!YIYeN zdCua(9A2ILTy$(xevNnXZDRD{1q&SO8i>M^!7z;n9A!gAV8d$&b7|&bf zowuClZNd4aVA>%sUfPW+^PrJFgXk@K*Oa%CVoK66QkwGiN%{_|dV1HSH;u6#tO>8{ z!9k4GrguqP-FU|u^LLNlN#%`fhvVtKdMd|z-CAetqk0Wf_MvQ_szqHk;O9??OA?-$ z%Axx1>s5|#mA6AVbS|l!bI(HOp!Y)BSN%&tbwRQGgU1HA65`m3Yz1_s*sZv^ixu7|cO_6+XE&bkb?eg_q!{2wr8AKh> z{e;Nd^xLQHczIjNpCoV7bEf^dKKm!j+w{C>f0@tz3VEB}SA~P6c&eiLxI|h55f>!l zc0?SGh^rCB%J7$~85TucWmTUPQEUoPY#b3Md=^A{fNtPV|2eXHdzYI^H#H7Be$$NS z#lB-AO_PW#6LDf9?n|UG5piE4u1Ul(ia00{*CdLiQ`4NkD88#GKBp-5j)>b7ar+{! zUc~wL;9R;ZVn^<#PjwZWlf!p}O=$WaW1@JQB5qd10fzUd_p{xeq{cmhKl-y>@*7{e zhV7f)|U9sSwUHgK&45$058YfvaUz})6!C%eS zkBrazB=^hF&q04Z2<<5Kk$U29TA)92qYK1viSBN|0l*$WykhQ1U=%PG7!Aab51$tZ zbTj96@o4ybKh*Dqf#9A5L=|wYQaW%hwn@WuKX5$oVW0`P8i-@u>wxHkyWas$0qz7A z1NQ@6z{5av-rcovt+xRi0cQi70Pg_OykgKfx!VHo1a<)41?&vG8%Xnw-2?0cTmSD$oLmA4PL*%1J^9+gR7&?Qz-g68!!NbrNtp@%s zHGof-3i>~@3tWMw|I_q;n*MKyULTX7>HjqSpQiu&tMz|UE2IwbueSf+Nwl*e=izrm ze20kF5b*_jqR1|)I)ArFvnAqFYC7gl1;5U!J}j3jrm%>o5b*^fUcg^ILd187_y~V_ z1d+X6)3Js{Jc!6{_m^K2+4CZP&0jlTE#5@L+lqKq5l{L?D*djzJ>2nK>&pX=&MJIl zXk5-X82>fR|BCn&5&tXVPyN;KZKCfb?pcpD8>=rc+Xp`#4q;d43s#=zFa|_G+f+}s+@tMi6a6?TeKRu8ft*-|4Y~Z zS#t9W5He7b|6S7jzncEfn?%s`f13VJ)BkDuKbtw*sOkSKmJ93ul$J;x7J#8G3kalk z{Mq_aYc9L*aUYFw*i#p}F&*1X@;sBpnp>KmZ!I=aTZrtWnZuYH_M1|zkd2jDEnKTc zWzgKbQi)am=YD&n0it|#yys|-R%9>I{k7ding@{|mPo^(mTmM4`tSj|n6;Bk+uvIB z)7)j*?Vca-Dx6z>#Jz=KmFkvpm&wi8u8lPqD=jpZN*E2KM-v023Z00)xndX0rhdA% zXf>eKfUpMC>Hk}ciwm6=X#|kInS%q_MDk;!U!=1PzQ-~q+RVky5@(((C?vIeP%@;* zg|?d!-7F~9Sy*JVTZ@_2|JVBe5hkNyNLYDTB*hNUXBv}|(s@Xcq;!)pDJ^|S7*b=C zlk~=PV{(!yJ~~OCU`!g$vzSaVqm2pr#OT;~W0JvS8j_lxm}6^l(Z@GGv<4^dotZ$#HSUSYvd8R5Cw#j3GUm{}Go( zC7M!FjTzDDI2flkLH4hW0a}B6hQBJiuNkrFPN%(u{CVu9mMZxqPaof-HUA&2|IbI1 zFF5_O(h{lF|5tk)Q1SN(kqrsRFd6xEgHC3(U{8#E}3w&%@xjES`L{%V*-W0)dMxLWqIXv|Y& zr~5nR*)fXj@k^gC^#<780lM~k*EhO5=Fpmy>rS^^-GBaK=!$vyRmc4O9s3oH@z(TM zsA$ZS_=<^GrEfRpU%}r&Fswjjuym}nAT|e&-_Z*Qmm(go@;V^C`|b|F2w-PmA7F@_ z-UCSUlTh10`RHT5IUeJfs9%NS5RH2(W1UN(kG@cBkLu!jR9-mFsV#rs8c@gn&$qg! z*qvr={Lh^2ZN6)BfM|1oXmfyQbAV`bfc#}KK$Vv0a@qe%{Evi`i;Mq3y5KC>)FPWv zq~8?zOV+f0RxR6Eq>~ldGPj14O)>`_5Wb^uK+lp*+5l7T9s(M>k z#Ig9R=M`}gYH@t7t zuRT#z{}=BkEwbN5cDl&!7V!xp-ay0;i0pllT`#iZ)Ux+QcD=|?U1YC`crcMY=r7;3 zFM*!>qWr+EEr;&wcHp^HTV6T7>_yD;2iq(_H~PfaQ?~UhoxT41<1e;N>W=tqB70n< z!SFY(nut&E*M1lAX(HZCWWS5}v{A5O19Yp}PkU@(r^cY~8{=aHpJ)0!ysp+u< zi7~Nh5}FdDQ%rhesv$O=5@J)+5qFCILX`RBOp`I)kQ$wyoND5tc2j~O!;oM~G^Qm+ zr^m)48)Wr;B9I)NWP*U+l!!m*U?~~@>ytCnAd~MGhCaMLDLKuMnqiDJNC)csprfyk zOG)MedA%VcoMiO;P@rc2Yxcip|5s<|YxaLoXdFIcnOWcs;FL4AXh2Zt@Hni~fG^t`@sUWdB?)e#c*4#$R4TG#)SFJNzA|7unnX+SO|DM6Q-}fDsu@hVc1w1eAt8>qnQX)=%7#fLWz4lXa*A!%l3wKlBH=RZFa6ZS(6sMq}$t2abDZeBy$7U}rMyLWFTOg!1oz-_~ zz+;=y{DXVXoITqG*D4Jg(DgMAJczVlq*wi3VK**fZRFaE|&)3};}8RiY*In`=<3|r%BqPvZs!PwuGt9cQ8 zLxAq1+$Udo?W2FJ|De~T9bx+STvtC=L-7R$;6o^Vb1~mB{@#o4YcSH4Ip^jfJ^+26 zp9E60wWoj-X8`^WZcMYro(58UfoFgeU*KOr#3EqN0{a1<0}cj04~zw_1C9W$2SVn- zUI1d=IR>eWdkpa3Koju)fCz!fUIpd@Hv=aDUjsUUuLFyLTYyu6Zvt-xz72%DhP?~C z2Z(v*+?YR(T@QQ|*cFItW8Huof!%@IfIWaXhV=q|1jKxF?$3b(f!_dc0#bcpJ~}tG zRZ&3H0aN&>q72Mehjl&Hy;v0vtO$M^dQ`+2q@6+=>m662K?LUcy9smtLbDQ-Da}8p zXjj~Qr1%P(fl3Vd^?fCOkQ6Up5aQU#7liykynR3vJqyLKw?twNK$QPiE@%!}D$@nh zIjh(e)tU|GDBR@$)fjatDJ`lb08o||12Ef|lx|4K)?xr?F#xm}0J(PW5Y}1@K$(0& zL~D%$s0j^#(i*8k0$fM~&>D94ch{gV5uG~RfDonWhT(=(w1NKG+(YG9VZLVo1o5SXkm3PQPvH$2gkkeY6XLeD)s~*z_et-7tS=v`h zyDBYiPh7xHc)1;5Be!L(5m%7TxsInLvJj-kVx{AI(hgQKtps6v$gT?1X4a%Gf8$5NR}iQMMr=SBYw>9j3f2j;hKEp2a<_bc05e74_{ zw_|X;V)O5;>%Yza^=Pssk~R%|`QQKi@brR{zbwq(RQA5ukGT>0jRCrGk6Ri}jM=+B zXIY(p9hmhLI-Y}gdabXr4}n(*ka_FvY#^6+ncx0_49gaIMazt89Se_lIt{-~&pbKUEn zsL1VPL;wC+p1$SH*AL$E+pK4L>|#59(@%k6vx}#HbfWo~4XyUnN?G%G{&Iu!6~=zy z=`j<2>zX*@^Q6)V6AyKt`3uTvn@RUud%=61uIt_`>6R{E{y1@Eb4<8BSV~V_JLHuq zfm#3e#GnJO<-P=?%*4}=_pVqQ-0ks4hJ4xZ$U}RKp_tQ~r}z4N_4jvd?i=^{tkgZf zogIbWgvNbbncPRBo}Rm5Oxhn?njZegFDLhIzw5g-|75IV6s2E!EXFnbeb^W|GyN6Q zqfK6nTJ}yvm$@ze9-PP%Xj`NfjF;5gu2Kr3(|kb>{70!{(029^UK15O9xdfYgcb1n;j z#JN!0OoF$5~*VO(^z)>z|pPAmc&T9GJObK zuSU>Tg#R}FNwl{I(deqB{}=f)Yh%s-n`6y;qR4Kz__zk5I1wU0f(l-K)fn!gxDT3t zK~Al2V0;YY^_H9S^!BEoudkhRy7-M*Cmx1D@g4f;0lJpIZ%Y00#m~P_c{3+^N7oN+ zSHFE`!FR4YJ4dl`_6K=voKxqqbIvzrs?D>FO4b&w1}>onRJ8wH(~30vU$g%;|9@@% zzpC^4c{J{t{$JDo*PQ=9xBsanx`OThqPpUE|Ni>bi{h87m64`l7h_ zqBxGCIE$kAjv{_U6!%dSZ&DNwQl#}4#TTgQc#xeS9uLrcx5s>O zRIIBJ@tYzZN~Dw71RE(E=Pt*(1nbt+^T#I)hSr<(-ZVD=%?m(dvdWwQ=bI1US(H7v z3&w)6ZpPm`u{MFegXRSwjkz*6fWm9goB)TB$6FJw%?oe|2Ca6eUp1hf{a;|UYxci3 z|DP8BFI}_$HT%EJ6G*`$^4G@y|B~^4-V$9V`(M%gU+nyUil2Rh22!)#8~}QNHO2Ze zyz>5lURcLwa;1NfsnAwpHWk6kzRXtafRJ+X`EV3b1@=rPQ($2VsMH$yGdh-o0#8p!J2tnk8iv8i;RE1_4ApR7!z@G zA`U_=&hAHiqe-tWwE>J#+dvxk+Q49}w5)@+oZ5@^Kx#8y076#62IF2t`inENFT28R z>`$ql+wj$85T`+025}f!DF1Ds!efZ|3({z~kXKu-%o@P!q>}z0^Hxd2|C;Z=Mf3gV zGXvQAX!?Im|F7x)HT}Od4`4+9zr_BhmPjS@Uv>R|r0nB=roPl4_!CeM>lv&guVw6k z1lh+wuh?oe+09NznF;s98o|~d+>-X$VfRZu`m1@~FNAhKwe9l4?S6`}M|MAzV+Sh! z@mc6Vs$~nQW!tF51*l~siF6j49^u~S$)38>^axjrzQA9uO2ipy+|c>Cp_kyu9iYpe zeQIs*BVA|D>3(dFwfXaiiy)exQp72UY<>~PL^eD=+VXduG5X$<|5pbf`GV2X3^D4c z4QLLeKx{35?SUKFCwe@AJdX8&vB|JwM!HvV6#jsI)o|CYW3BQbaAR7>B;us(mO{ZB2?)nfm{ z)tB4<`9QM&!>h6XaX;1C|ATnmq)WE{&*zUI8v7F2d;a<__{$g6G%p~s=SB9vC|+Dm z`xl7pK#|tKU;VjAgW#_&T{ISYrRmj0eiI_Cfk-2xmKH|DUx?<#jENxoHY)h}VckDo zwe3LW>B;AhJ5bYO_5S+x#Ez%y|L5D!EN!gMTlDGmf9O|r*iwKwQDQ0mwTgPlKUF(If1ml zf){Y(n=gIup)tVUG`3G;_%5up?88_-@dBU7WBZ>0(L}HV!0UmZ17Y4W*xo#@-C-bZ zpM41gwZXmuCIXKF(}CXrO~7w~)ZQEeP6u8tySyhj8Ev_|HK3mTPeFk-|9{Q@U-SRh z^#7Xuui5{X&;I8vkxB%B+VTIC@qb0{KNVt5>f@CH6VbVQIsV-7f0G<*pW^RFN#p-! zB~8%*Y~jb)Yg0V_1}Mu{|4(hayqu%|r}FG_X_^)we&~lM>f1U_wSRg4edmuIDB=P{ z+=0mUxLn+Uh$9f${2~rWWZR3lA(4%Jxoqhx&1Ux3))jF;A{*FW4#;1w=St&rMBL39 zZu3vkxB5;0H|?WYXC$Z))3ej*a!%{1H<2L=oeTMAkB5y6bM}b z*G$9!Ni&fM3;<>UNjqT%l6JxYB<;jBAZaIN1Fr?%4QvN|07%-2M}efBcosSM`z!czc z;5cABFb`-1QXeJ(NSso|II;gpO=>;X;Jn(R)qqw57gqyykZlCJ)cHTTPMMQ`moo3? z+O`d3Ma~jeZmG>~$u4v;vz>C}+8jB>Hfu?*@&S>>R#$eJIoIiQQF1o< zon*%*^fF`_n7PoxLNVQ*!)bTsJA*=#F(#dC3&npWSf}BS;TEi^_`?v7Bttwh4=<$j z1o|%xl6A{}F*B+*_lM^Dqxt@5zCW7p&tInfky;^jh(EP?Khi_f_^!w&UBt17eAPu9 zi-?m^OE+`1b2$ETUmK#xw!Cfk_Q{_<*1AP%dDq|W2tC{mc4{=GznIyu)8yOt^n0(? zJKL5Aujt6wIG%o2vw;4)U+?;Llf$>Y{DS`2Wbu3sA}&$H)rdG55%(gB^C;qoYC8U- zNLL~9pHRy$P2{(6{V;ltwma_qCZhM4c~b^;-tj?7eb|s9U0O2FpT&-b7EE^k@bH*T zw{|_Wx;LbmOcx*7ft)0YkB`Ps0DAuNToCV_^fSt3m$P z&9KhLng;z(8>|%X)0AVe@O!bMS;aom{~SQSTgQrANGG{Cj|0*M*qtA9Gqz*6{zob! zwTcd?2^}OY=jec_T&2`zY+zsyULIn+0cpFx&$ixYdz8=i1fT7jeYWTNY_Ig%CLNLz z6LnKV>0*}wXiWTmtYeV(ah@M_RBSDDmRY^4>AdyyEI)1m@<{b0m9vbE#Tk7yQx{uT zukkWHb@i^#_9s5uM}4+`_Sp`^1I4g%W!-o3+3xSPO?9Q{$tE_!L0CrO;Fds)$MW|n ziswgNQ9K#`<~Z`4*e`mYa5-!QKW3;-d7q>*>goQQI-+YFD#yIBH%8%D$R~lG=SZyC zIN@CoIM6#^T4c#_RbHf_+(ctG=E?k8$MSkAl3r7b^zM^BVmUvyCCZbuZ@%|cf;^;? z!!5BTJZ}uoOV3xy>v{X7yi^B|@VvdNychD%7C9LI4YihI>d^Ihu8zuX97yNz{I*IU z6YxB*74i!<4SDEK!tp3$FF!Ay*SVE}dl(w%YK=_zrQ-Hcz7zxKTb@6fwPCHQy&olC zZE#jP^z>V?f&BgtpFMk)o@aY1QeN;GU^`(W*J4rp-Wst%fxD59PTPXj4NT-^u;7HG z@Gv@r(hQz7lB4*h^`o?A=j0p6^GMgj%Yr3O$2AV5Yx2~WCq5CyB(7=R)L&lkYT;Q$ zep3F<@6$1gc%4h1uV-5{l`}T7(f((C`8Be^ifbF+*L&bh=tX$>Rp%Anz|(7vf30br zRTMM(a`CSsjiHE_74g$G&DX{n=smeF;ne6EiziL*G&z)Q?fWnAh$7xm#Mg@WT@ha^ z;&;{JaYcTYui(2IperxzJG}6Lu!6%6|CyD)>;JaG_m8K)+I#2-oGtj$S%ZNsV$2aN^ z%t1Qxx~UDk2{;7^`q%9OQoiXxRF9kb(@{XW-VIo#z8+)C@HbsAUDsNyw2VML>W`pb z!Znx4Kx!990lNWHfw%{j4#YLF(ZEPxCNK(^1&jrb1ybJz!v|b@IUa~KW&+xP6M=T1 z8A$Ct?txz~<(rM|eBct`B;fr(3>)$5KZ?JlKA6#tD5O6aPx<>XokTjf>54uD4CXo88Zvp9fm1C9q zgi>FT?zaijsP1Uli+uHfp8#6{KLeuc#QkEg10KP4Fz^^K1b6~S@7XEfVBl#WJ+D82 z@j%q0oBE=E0_pq}SfzfL)Gwp+H$&QVthC^s+;lyp9c>9D&1e^3cObpjr0whtBuyvY zS+3z62qXSvk`@9}amfKu%_^(Tf|E*~NC7Gi!Dcz6& zv7^bEJ1IK|LA6rTV+j&tVxdSRG$lr-nDoX}Lu@)F#HOalBg__5C9wQ7f7TP}2Zv z8o<9y11Psds<8hT(g3z#O#)YdgrvT0EmlNRkE5U1Ag~h})s)ehY3VQ=uE(|m1X@aZ ziYXRf=9uW%ktRb@hA}lciFyi=tT{@6KTkvYpZA&hJTL3<_e6ARk2I3FQR%)EMwI%a zL;1ONEU(l7gTkBtB>tT-=?JUCg1iz}*rYL)H6OOx&_L>6B9GltV!PRjzbFs&r9*h0 zV%8dYyvxb8=Gz=z`Rej~wQ*cb;2H3C4fysF9;Zw?t_bIe4y2nK!S{7%4H4bOb8d%q zs(fxG-w>X!3v$)tyesuhl!f}+^1``E;tLxff$CqX0r+?!jjn~xFWtR#)ij3jJFiFF zC-%{{biJPKLVj+~_DrAcJH57v$BmFV?d|e&3&*w8#!AHKa$M62p5JXUNf*N34N;vc z9PL_uOb}~}r{v4Ed({QMf4YaKeXgmOd`)|Cue6Y@L-j^T@6tOw|4jLks2;@c5Y;PV z@T(}xvD07leu+5a%{W1IoH6mf4R8VYd4MyH#QEw5)~?*{k9Wa)TjG?@&C`z`^P6;^ zC}RMQsruX%?wGDwxng=oN_}MEcv|RZ0aK1$gEbc$4f(aq#Fzs*uSlc%hz+3YJ@+@| z`z(-ESeK!O#2m|3qF-2gY*+H# zyN>+u!-V%&RDgIA#hDOsyfr=6b{0HQfbMwY<_32?yU}8b-q(2Y*(EvP=b|aSYD_=T zSewWffjGRSSf##`)Tau-cNm{%;zs#m0oOXX3bK=7jseJ3~d=~e*g`XQzv=p@ zE0KE?!b?MJ%AqpLxIGNhRNx4o-C|VyD#+v=sa}a z30P?vh5Su`I4|eEGl0}S;-2~W#sH~Y;;5-yJUY&Oj|EcslqR*KQu|8f({%@9rDYZJ zA&H?*c)6>A71-Vi!gDXylUOVD-xEE$?;!lW@OnIto4_k#C7*F`&38y=@XA;RcR?Qq z6*5~d%}eM#CqQ*t@4hHE9cvNR3atO@OC40erSpFddkLf)IpLcASJVG$`d>}|tLc9= z{qN<`|5mm{sxW}k98KS&ja1797TF|f+5Dn7+OZRUkmYX3h%>;G&0f35$o_5Zd0zt;c1 zto{E8wI%?&kOsit@&1$OGH7vtZZ6-nHM-mQ8JN3f7}+J$+7^v^=GqDWY`*x8@`v`^ zkcKhXC`wPro3VJ=jIDvoHofxI@q%ac-)^7jPW3i97aU(fA$CA ze0cYlcDlHjKh=!^(F9whohMyAY3j8_tAYR38c@gnFS3?c&6@tdq*$B(8$JY@{$H<$ zFNUW7&$d_;>ATV4vKBjX?AaNy=}xD;B-`dN+pC!;yv$5{f6UyiR&OoS+cf+C z^4R}!OQg!^pW3#+64$0L39zvA!%EsHbZ43KT4<>tx}rEJ898V?k7 z&nWLz>g5`U19hzNdFw8S=V`>>6{>e-3BVtlhn}nZ-z&$8Ar1coejMrkNwZ%!aD3%< zcsP|oX(K&p^b^3d^-d%I07>i5-#_`<6oe7SVXYUz`&G##?P zx?+(ZhrisQ$S-3Y=N_xZ4)>QMRZB~v7T5atMEYH zLtD>Y0!{;N0p11N2wVkx4M=SqrK3zX5hql*!0Gtgm;YOeG}3@?0`A2+J;=iY9`12& z?C(?9&u)}-;S*5_MOZgrC2e?5o=+gE7MWw~oGF!3C0A9)*U<}I! zkd&_18%-I8)HED~z$Rh+!Xm=L!>BA%TD&oZvhYwTl#pb|G^OcB@*vM5BTx!7gO#TzT#T4>=KF*xU=M;Gk@fs95 z);wscxge+5;AnKzYq40wQj$L(2)#6dwjzkL@GsuSNwl{ibr}=+!mDMQsKt$l zVifqxnTWU%5tpKICaK{q^R7JKZBa}Hkzb2i9E&KnfLdIKh?5cdr2EUssKur1nMhp9 zP{Y@|zjOWP&WBTX)|=I@?RR279)Gzh5eId-xS9fdF9(nHa09-)z{U86lkJ~{GA`sB zj#FuiRs;W2HK30DU!3Exm`b$xpPK%MtY=OCquKwy_GP8{s_B0`0w&qW_SB7L|6i*8 zFSkUhSpOHY{jW#-PZu;A+rbaiX8ER~JV&a_KHTa^MRVvZo-@R z=!JqCNL`ZV08j^feC}lkTTWz1dLarfS!61-m6%P^?IREAW@@8x*D}mnT)U!ZF6db4Na8-EScb$~)HJUkvhymU$nL4?=ix68A>tcE{6tOj5XN}AubEY`4_t1tw;v#>e8IS3lf^RD16_v5^Nb5o0bI91ZW&`>P9vkl%epiYX z;$(aHId!P2halb~7dLCCKy zfBzc5E2+Zxe+i$pF~_dO|Ip%pX!gH0{;$RV(ENWckN;0)OQZ?|K;!>S0!v}zlkHoJ zneuGKB`#BVM1K-PQ15{DPsRSV5aZTnCbMf=k=2A*i%li2X?APP=m&PpJulm=s)w$FIKL;4vrNf9!)go!cnv(2TRb-Ooe{}RtwhISl7^YDzpngWggJO z_?zOE1dNwrv?^Rdb=nApBiNaaIQrlU_QR2+PPxPv><>COrv5Py5bd$=RHt+ODV_j- zuo-@Jbw*1ZLi?`Bhrh|U!k15A-~$zZ3SUlv<|(DvF4}VC)POqn|5Tf!#Fnp(|7+v_ z+W5bw|F15thi8mii~k|kMrh;zmpcA0w?wK~{}&qnZwK2y8{_cnTa)c?b`{&rrW`rY z1@Qv3Z$st2++u6aYyU#U`Vp#Fb;WTP+liqe0;H*D_|viZ!HgUnxu$ot%o%BLDps6fMH$22$VU zdH`q$hT$njT7<9BzoghDURng{QDDEX7D0(W@dH1m^(AW)BIG$#*UGU-`pehW4|p5y zzdrh^xHj}q>`v$8(jp`yw!~0gk2;2AM`a{q>#zWLpTc0Oh`MBo|NGE~-nxhyH2 zzXs;XD1-LVoTlw?%zS!v9S>pAm@zjID;;+b$B{mV#*LLF z0Dr9XiLJ?}~DucWQ5OzX!_NymE9 z`t(!sJy@Bq&j2OudY(q-?H5jIt#NEUDW8QuNRtIK-_rF+F z=-$4^Qy1TUpJO>=B92w0EgCYaDUBs1(IB^lD>@Sxs;;jAUrbQfF$0&M^Rp;^bR}&=iITUfbB5k0^H%!EFi{@8u z7)|%}VrIimlW*VC@4Z^@Y+D|@0$kd3J_cZ38NS*4Nygz%6V~+$e*3+3j9qCyRBHK@ zipCQB)r7V|yAYszr^f@^w=K-BRr`jr+1alT|BW$Gd@d0u9?#2JThceac?aibouBLZ z@rOVBg5KR!p1wVDQe=MNlw-#}dg9ocg0f7;K+CdttWsZ<`Vx#q;d@>Wh)*0}2FjW& z(q>V&hqPH}4ro8`>Ve*LQ=b=2a%Ef|slUi$`S9|*pCg_n?N*c>@8p`;M+jDjw3+aBl`-7*Pa~(8iDTt(}3>-(QLABfT(8nEs)~; z(D7x!AAuFXeZWP){lF!_-N1){9|2ba4*;J89t1uIJPF(gJOg|M_&e}5dHW5Z4)^yq zupV$1uqkjauo>_GFaUTMcpdO3V0++cUBecbr1}!59|tT1`GwZ1oj1n0{a68 z$=kz#gRmV390E)Q#sD*c@jw&M2+Wc9=L3ggyAU`GSOy#cyahN4I2V`-TnNkr-V4kE zE(eYSJ_yVP(tRB*2j7msNx@k4SS?r;o_{+2UW#=C*4ABN z4qX}pm>z`Zg4J6uNZdcY01EfN8Gn1vudDF<6LAhjJ4jrA&m<4u-~Q%v<0lc|EKByH2t5Z|I_q;n*Q(d=>IBPB2`8JF09{E zlVgvNV?j@pdF&DB50Y&X51d1!XEgD8Gfi0_qvLFL3=9xIro_i4idrJFiJNSR?AP)9 zy>&OTI*8Z(Gv^qIz9-(5xHFm8t|U8&gCtu*#LE&t-Uj)b4wg&QGqo2K-VLk zJC5f$#lFQ^iC-mu!s^&MDwFJwVxIqfiN6JJr|_(_pKiS=-%srE&_G|#UEx(b@I0M# zy;)s04CkHB9zuCieDpSaU)?G^INh(jxNG4Lg|F<4zm*zo2mX-qQJwkF!<;AV4Gv3( z{R(e5Sl(86LnT&vh|JjsQC_TMf6{Xu!Sl~FnPQ8IF7#~a8C}dXyjVZai@i^U|183V z`|I;3;^jmFArJMJf4UT5%GAJi?8b#RkOUDh=1F_&->TUnRm6%jVI!JMf{kE z2NUt1B0f#Te~Ng{t9=|qG~Uq~an}NLH!R)TZsJ@2Zu@BWtfQS@U${@~^D5#S)fxvO zKCp-y7~Y1Vy};iG(Vik)HM3AUmMx%fsITxAka)`-Kr~luClE9>`v4dV1h?dl1A;Si zj{qJ7jshM9Vz`SP2aW}v0OkTu0j0CO*4gjtN zf=hF+0}cjm0uBY@T3HnEZD0&=7f=t}4+Pid{sM?TkNX%9_saRa1R(KvNx<5;=M-QQ zAUHYB-=zcFV><)b1(*fw0R%VajsWHX`vD7p{ej@<+&2LoK;rpaz*rzSJ2&;W%7Ikx z@pKJxdme@9e(w;|FgX?>sg0 zv3pL;!5GEgmG>jNe*jkLTMX?GZQ~vSM&eX{C_q7U(Nql zZ`17m%VYn`Es-kL|AqX2{k8oSe@Z4B?cLD!(%4Zj*7>mg^Cw999_bz=ZO>guhmWcY z&clVs#`QI%+jsK3?O8(>fbl3v6XMGaP=0wiN83VWDkWb&EF zl=|Zs`@8Z3YdJsABw)9FVS|F*O?nJ_=k_jPxBb2Ofhc@frSCO^_qoIm(6_uVR$4HO z&UFD8LU+UEhO`=de)k?g`rgy_bfCf$_;LgaKS2IE-hMiYe~#jtL$SGen0 z@z2S+!Q-1#Wn5q54N&{qLiYa%rlT&!#ZIxBTXlkJ#6`7Rx%q!7bAQj(=Kii)wPaAI z(loewQ({bPnuM5uHpQejBAg56$km%-Q`2J-^z>JBLPBz;$(U|PjZVi5wR}QrQ-UGG zkYGwQrX@zF$HpUDrZK5c1d^kZOqe{|l!!m*U?~~@>ytCnFhzF1FwEbpPfAWRq-Gdn z4bp-7KA7ZJAD5EMC&$(sGQw#JZGI?FoBK7cl64#9u`|DC;e@U&7DyBc| z>?VOL&?<&N3tEd6QCKUU78}5|tdvH9x!}X0?)>12571#*A5c&3qEO#*5$yK6(b*(@ zfXU{}HRY8$%t*hG-A^{YQf`*aJv@iwsO)F4F2{Y|TUjpdw8UkxIT@l7RmM`{el+A$ z)DV429UQ-X&*`f}@IL3W^3EU}PYd;jV^EKAye!;{)nSoOS*2Wlfb<{dFuco6!5Abh zFvIx0!0cj+QAc^a+?f=HeKLP1kWTTNBrc^W51agckd--k-d;iuh5ASG!p~2!h3Iyu zEGmig77y_<7^7Hj-q#o0NIEhCK+g|mC%YHNJ??vb$e`4>o+&1%kQVgjk*!F!kNK%$_?!kpr8&te6jyWX3I(7WiVcg4?YO=Bct>5Y}H zF%&D+`!ziOOq16&(xa(T_brgtf#>atXVI|o8oldYxtAcG?>cr3qH`$za~FFr=d1t0 zKKBM4K3j>K5pfY4qKI?2cwZZl_COT7#$WA$S{#VTN6cSeFtxN0A`VRy6X|lzo32*O zAAe)}hvk!I#<*L3---4eyf^4Dkc&~W;mM8B}~*skQecOCiRhY9bm zs2IrD<LY$cZ-RmbqrViS>?%lCFdi|Wxyx==A2V23vhgIhb6~z|YkG4EO*ZS?i zWv$i*-QHv4pjQhWYca;+FIW5{zSGpsOZ_ydUy_CIc5S2)??+2NaDRlPA)@xFKah@F ziB;-{F-H9}I*!`QC0J>}0Faxo4A>Mn71#<`4r~KN7$D9yf_imR!*)AxB=8PkGVozw z3UEFUx5gF#(amEEfpGI-i-8XT9{{eD)7Ju#=6)7P$J2GjW0m@Dj0NFuy3Tq)>J!ki z5%~yT0b&>13~UB`4M=^+*MZar+ybQX=$fQHo79)1^6Dc^kCm3a$VcUW3Ty{F1O$)D z4g={vj{y4uj{&I?(IkhYHk*W8Le64sqqkHw+hfM>9_ngKl41DylkuIvwSBbJX#{9-ca-E2}bh#Plfir#qmmZg@`UA9~Lr z;q8x>g==+TU5Irp*6mmiV`cxqsx4X#Xf@zh4b(yIOV|II^6VwKrFpUd@KVMA7HDGt z+8BVzXu$A8SY%iqX=ouSoewr7rJIaNY3V~~z#%p{NpIva?c*_okzh<3&a;?IF{6zM z`o!qicw>^mWEzs1o|tO2&=!9%)vCZYO zI`CHupAni19PEOpR0i4-R+nU_5U@xK~#PMZ1}%0hgzyj0<& z=}r|+TGlF7Zqqf<9Z;Mux)$12u8_F*lT;{-#g0*A&sU8_u2yWI7y3~7efB#-p4_x! z&ZH6cIuF(gd=0iLPv3US2k!S8?S1U_$3N&lXu#<)u=!ws2I!)KpC8u!<5k-ZWS*X! zQ|lXugZ$;!hVlE#&3Srz)6dt}&N*HD#;g+$FJw$Do>aseinMMbo@E2S&Wq=xMZB|! zPZaSuqS*Q(eo(|G&h1Oji|v2o*L82(dfYPYgYAzWdmiL~h))#pQ+cqr19Ve2RP251 zsqS0Wycsj$s}_IU1e+CP3HYYAvsPK}Z1~hdTk3Ph`ptSWc9y6AesjR6=WL^F%e&<+ zHctHMOUC^5DHZX3i*auJE{5FqP5#EQ6(`aP-irG1kHz3*c>0s(L${2%^VqDH{!z55 zB4rmykw%G>Klp>)_vmYlowH?InXza_p22_3==>p6PW;dhPt><{oNE8_{`&@Im^XkU z;_2mueTNr55LR&b;XkwTcm3a1#(E5;{H}-{xtl)KRcuZU-w`&U>3jb3k0M^4^qv8_ zDH-h^-7qMqjpIue{>;WDD}fGn|ar^C*Ha-xL1dZ{?s_1>g}a*IiHOhF#O?wgPQ_AeQUum z@jS`?jwks$jzWAI_%gXYmD*W~T^NFN#FF9*9=DtLKr|YfGv*Ip_lIJe^F_! z-Db|#=Kn<{SS*u0^^0#omAcV1z?ZH8mRll~2*8@+{~+q*OE~_ohqX6W(yj)U%lw~o z8=PO0bgPQTu7~Su$Mbfpz`l z%O{HOR5*le&05VD?rZv9aMY*0`*#_(BMnBAXg*32m*X!d;jb1;#KHK>ZHTxff4Q!j zj>je9Fhrb$zZ`=|v+6IG&@qbMpQ_xji2D(7w`y@h!}#@7<#dH{*Q4qBtNI;R@N%kZ z-qhk^{pDcP;@U-=w7(p@zg&Ag5JLgF1_sM^z^UI(+%2A`Qp8D%IA-Fg zQm{(jd~loiI{@Ed;-vIgX$b|_LhS?eVqEJ79*V~m2R+TTUZf?w5&OYQxv32q00bX( zQJhS5x-DzyJYC~iQ2STUqLTfO+2$+FfB1w94rCMQJq|!cI1y4`!9<(6*jeJt za|MN@b`MG}a@h)PH`^TfL9x!lBDfG2Gfn?fjeE6b|7-f6+#H9)YU!of|1v${MWs2M zj*r?+X?jFggSTfKxEUNE1o=5L#f_J2v9X8%_mzSqY82Sh5C`{)$@7XpSQ@IO4!#^Bw<-Ek<` zn4GHl|G)u?sw0tmKE)X=7R~-QXG;=pG&4Z?rgNF(768xR#EKV~!i>#s8vIT`^!cPzWJ`w#98j$<_;N87k{y%a{bfw$> z?d9?R73c=g_|5}ZDF(PcM6&-$&y$BVk)KZ@&v#Fy{jc~5A)=GRVlC%BIDt66kmno7 zYM~@weE{`0;j14#k$@dJoFi%iDjXDc7N6dG?(A3;Qd5$B*yA z?}M(#_Zq2xA}{A?7+gq{&Oqms;#c`{8xPNCGLk+XXCMHhZ?e5w{Ga$sI32#j~L74>HE5m7~kc-9j)$}dBZ*L9*O=F?+H&| zzoFhkU-hfozSD^x*}~tpk3-yyBpL&*8h6IuF=>$>kjP)`a&ZZ2X@D-5O)s+DMI6bk zuz>?~(~Kbx%wHLP%i@vKi$XR&0d7?-?nI;k5^*XbZIFly6mhivaw!ywU4i81(;bMixnI#5UdLWE zOd^C2ib;)5ij6m=jY*0%#U_u2+gPe8BRXNU#{Y3|xpQbJjsJt%C_C2a$g}02L)Ixo zs2@Ise^>smvL#Z9094!mM~TC~h71QRWCt~ok>cPZ7jQYCF*HEFP_rF?eJu|yqmu8yvk_&c)A$R~-eleVQRr#u4# zqow02W9py8e)3ULix&~`0V2N8U!G5-)e!N2BHr=u%EyR!7m@Zz#G{D#lFP-5i1Lx<$1HmoO*(&2~1 z`MWS+du*dI;Bj=&pz!!P;O=-_@&Q0_Y+Tcn21K*uwgQI%OMp?pTYz-@44?rBj*aty zh@Hdvz{Nn~3BjRN#F4_)UZ#a0XoR@=T>TfJh6C-ttF*)GO2N_#1|aqdB<1L*T|PbSveozJ-;1A z7A8L-MFTXwA!Wn-8(68oN60lxxJYmoQq?1kuA|atiANcswCF(GA{)c=nlNTt_q^Aw z@E4wYG8xK?icMuXcGenYQ9pA6FDn8wv;|-e?t1**sK2Q!#C61@GwIEB?3THXX5c#h z&5tLpV<6`_o~_&tN7q&2FP`?KaqfeT^P~;n$IbNQL047cG^k!>Jrb`0Z=OSWI*Jb# z>6Ao14gUJ{i0o&7W1aZRcZhfmkxoV}-xm=-VuLXepu70EsUo}GUtbmxPvNf~MxVTOPckqgc-) z;!{LAF%jP(;sr$fg-CBE(gmp%>qNv8oyFHJKsWHG{~TGpy~|Cdn;M55ziGzvh|kLF zvm$HEh!&q84e9jGs~>KS-3`W9#4CwnHdRDX`Bh`nh{73;yy-BHf*cCnCPXja6!kdF)>vlcg!rc!LTYjVz>78UySKoB+HL2)Qfw!72a} zDUK%Bod87h;2s4;d(YzmmjQ7MpT7;-BOX5($MX2W$jjpg({+?%)k|#)KR3mOp?24f zl@^?{l6RrD4)m0p8Y$vS=={XD3;`0K5(UKS23Nvk#UuiWhoS2t9tOh>+{cW{hSbRI z1}Z#?h(n>czBS<=_5@D8oi0FIv>MQAphjyzCH^nZURqM1@qa$ydo}+*P5-0me{!|> zzp{);i~ox_=&|q@%!1z_1aM=E1_Xr;kHb1GDAW=$)^=mirN;lwlUkxHlK)e9w7xRw z20H;U^0?mt=h0?x%?r)_g~k-=BHpip=NnVWpLw)D4)W2gDV<_6#2 z3b=^xPp!fUHla+?BIE=WE_1tlFY(AvHWAqu#0efz?uFmXg}Kb{c>W=k_jDmY!0LI* z=7DtC>l@MkjP1ip_d-|;dwRhUgm_AO38czMQ@BO)RYZ+*cS7&^)ucMJ78fHgrSAuK z=&i*f9+EiCWM1w=n15RbTTbFNFQmx|#&OC*wi_8~-aO^oGEYgGtokq(b(oq6nk+Kw zIOlklpOexeD!EEeS|6BxzWKso=1FPCJ;%aSl+q4*(m2ma=iTW^>#OA3QJL1K@>ow= zMCEz6SLTc8N5{5?&Wm0Zs#8yG)4SN1*DIw{P1E*;^kKxCDmuC*jd36rnVRPQIHaR% z!0XH{{g$N1UFAKOj^zLI_gvv)NoOYF-$ZUicVttADIuWnsFMlQCqx|KaIz|!SRW-)6zkI$(2PWeAMLe5`UlsACBA(MY+qkxY9!PWBl)5ZWF$2Phde7-d5 z2tA4IJm6D6I{!qhQojY`hWMM#Pwh%NR$6k9kNP-PAo0OC)=j$U0$?W~@x9%EP9Ugi zRs@U%mH^{`Xyf>KPT_Bmhmnu&`v?$C8T$&@3ivgU@_hpY^~$~l zQsa-~_&jt!0g2cB8JGtA9Z2_i28e59wRFr)?QA{ZRA2+(G+;yEEMRls-9XHH>0ShE z1w&0(V63#fhU+DK9oPVfvbkUG;ahPpST7eZ&1N#z2I~NYtcQ zR!2^*-TMFRoe6vtMb^N3xKBwCK>;O5Kv0elARKb!m;iwgViE!fIOG^$AjyPe!X>(c zoO0}Pi3g~ts3>?WqN1R(DAMPyYxzyGW5&fQ34Q1I*iQT)?2)zwwi z-BtBoy{dBMy7MyJIX+j8wEuy&5j1s#ho$4gL7!FifrYoBYzm=chz?87CVryBY7!)V ztjU(0Cf&Ot9h#}%Vx^OUapTx#gWpVhz$q%8ZbdpUO=I&vF|ISNmpOUG*B9H~i5;Kx zNh8$tmnhpi(bY-6)I3Oz_CfE``mB<6cRSU!qPyx&da4I+E;`rk>59)gca}Iyhlx<< z8;Y(G+dW;kB;{b1LTP(DJ!hid>8k}v^0h?i*mFq#U5*QIt0~_XRlI&#f8C`QvP(@% zba@MWxdpyc)**>apOp+(Sy|0WXJaL+S*<-5H&FWaUuz%bytw42=p%(~+i#uNeGYah zeZ>Ft_fwmN@D=1(a^iybrsa-3RPCC@w|=vyu$lE9?^ZfCD_xqE4$Ml|Wu>FCvWc_O z6`kp|lq##!veNxn*<_t*otBkO)JoSCD4l4(NO|8*ecv=IorINc$x27^XVtM)R+kni zo!N1ZJjZpPK3Vw5rehmN*Z3mqKXV4q;92R+taPGQx-`)_t>=6(+!DsRXy_Qugsvm38|iCXNMHfm+!KJfn0^)3Un`$i6LXLgAf1j~M^PvpcNq zuWa4WO`F7K%F5p9Y|{-{>42$p4b^U9nehb-CxtC1l@pr35GRiVooEsw-37n&bkr^ zjQr0^Avqb@xrPDI>B#@fYxD`$GNxu~<&+VlbG@=Dk|!&3bhb~+$dV9cH~OBEk?!^S z#Cx=?Jv}-mzGLi&SS=$vQ|rLqRob)WhagL-TRd`C~vPE{Q*42jUew zkiY}7#XnyDOJ>+Qvs{8)=_DmNHom_Yyhx99biQr>W842ErzG`pI-}!l`QMiRJCs&q z*!DkX-2Nwy74+jro9$6xv;d|}&eB?X^SvF&*r9MOHX}FIR5m%rO~qcN$R@{=m+#Xq zHEd=cSK*d0Hdq6ldkt*_E?ujq&C{y!ms8D;D!w)=jZ4u#LG1m-}6?IRsRdN`sXp5arBhGJD*KN}7BfQ*0Y;$A|n}pT09BgOwIc#mnn?q|w zJauu=!9QaEvqD|_gtB>&eu8-z#UQ8tD*RW<{zm0k_mgyqO^%)u-B0c>_by)RyRN#I z_{q4cIR|Sye_QD=taK7qx(6$}5i42KYRw)i*>RYXT^4@5bkyhGc2qYWM$@h@-b- z**=#yed1{8R41h{ah?sKqhpXpgsve`i7sbcQfy3$c*LlEX5_D^`1qm2U2*Ir6O}SF z$>ofV9yY)gADbE*?-~-9JR~Y5W+1_a$0c+L$2%&)6_r4I{2>?X-u&+zIy{+uxx0nQ zw%iFrlVg)o<6>g<3!Poq=-1glai|*QV@vPOvRSpd6x#OxcK^TJxL(oll|BB4ZlSbT zP+T_2G2ZNKZ%(PreT=n3iUQgD|D0_6k50JW5(TE~e@4dt#0Jo6oW{xq)5;dos*h}C zBU#zLv(>zPtNHm>HkfC6ywhs@va&Yjm9-^b7$xHt)wciGx5~F+3r~D8_th3#7roE; zuJXS+qRzpGzxg(z)|w`DS9R)%E#-np315C4%q_~l{C+G}w&zy!_N~@a2-JN3#RwNc zj;k7_e?4jWjUP_?erTs-cOEzxxc#;(JI-WfJ73v-qO8VKt!(Pgv`lGbvu`y=AyDg6 zSdG(LjgMN5?^=!PTaDvxSMSw@HJ+}Q-RYmb=YMlwVdQu3T&K^;H)Tw#bx2E&*R{PA z+i6_yR?M4f&EL2^IMd#_LR;r^M_jX0YL`GjOCWIaf9`Z!{Y`#}ZXG)VN+QjkH5^Ib}Rh z)|@<_uzgjy;f%eV$DG63MdOE!jj=t#CwpeN<8q>>``r05_NMOxG(cT9nE8(Scwjx^ zDjsumCCdt-<{bYt6*f$3ZNx8Qcd{mcjMcFk))Y1|mjw}u;vS~L_aSssHD;)S8UI<0 z8A{&toM~KDH(1gm@t010@z|k^C+evz9xJroRax*|i0RFqjzR81}_y zlXrG2n6vrlktZ%nXgA+_O#oY;^6=J`e5`@eryNsq?+aBQ+VG#MOR8QM+2YXHo;Pi> z^(hnjCv`r59QF?kSO+;g^KSY)ywk|VlY3pd`}M?{qZqeV{v)(cJ4~45|LV?>+pcT< z(LK%COGWu-tnIu#TdI^^=a97x{ivv^*EN4zNPDC9m7#f3>kP7_hkqdc7sJ8u5-95{ zwuI7-p?>ja!ZWS6>3st?v5(U#fq=>XIeNE?;p)@c|JNS>xA*_G_y3Kz_y5(+?Tx{2 zd;YII|5sU)Px-a|f0Yq#02KgdV*al!uiEnJrY^hg2)knNiCH(TT{e|Y__;FvKSIeB z?cbdp^xYfpY#kYVk9+>8TmNp$tG2w_?%#Lqe1G_fNoiF+XYH`cj{h%F@72c3hi>S+ ztp2;(zF+lLLiYY!?eYK967KAa?GpHv5(td^KQ$xYw*R;1|1zV%9{;z;|LyUAr)P>R za8}mP-=6<_#^?VQwM1w6`2Rs;KwQSUW&B^bjsce2$E)#wGaG7bz9o&cIsR|X*S$}L zo2WI?>RXTf5BKI}GWOrp82f)%U6Y9oK~?67R#9__WlpeZ1JIWNAF&${8vxlSfK%;X z>Y9G)9#-T3Vv`_qTDPgNsqDd6N4to5%`(qe(k`nnOMHwYX>Y4A4NuuVK(0TDeSnd} zV*3EegKZyh=GT|A=Uc1}UDHC-?D-b@dUW=Di#y)FESdTEx7$7E0ez=RoAecWtZr>L>1*5A1%dlT)`3@KaCg?U3FsiG2Vz z0c!7FAb+bh3rzcfj+|ePzt{<|K7s6|;_n5;ULX=)1Y=-R*dL1BfY=X&K#GP{Cp7;x z5Vet?=0UBAkO|MU{Xmv&KcGqTeEREuOLxV#|F_rwvgLoL%a;Fb`QMiRJ50^&+B1T+ zLtsQ$7oFkVe;4^bfW!X*pZ{;#|8Ftme?)C1{|iO_|9(P|{4d$Cl>e)GB;1HolK)Nl zyso+?Ny+~`%h>;ymHlNykjqr~mM4|{&3OeEsjyCD|5mna&t_3UjtjcIcF&jHet2ZX zUEg-zTy@Tqnr5%15Oz)dSJ`W;yOdAUw-f4K9{SeLO^3etv9I5O`I`3sZ7l`c_P^)4 z)X%8%`pEm>n&0bSt@r*qyTu9Hmg4kmDUK=Ge$9n@e$GF5P49$89shgXtZ$C%vV9`; zy57dH1|xrqY+n;1`m3X?Y=0>-xhdO65JF`7cqlUbFetYFzlW^8#+KF9^9l5S0h9l; z+&RYb-=}5&ztCR)&tCt}6&K6WgJDW;kYxoEQq)3&2`R3)gyfVyve;nE&;(~(O5D%{ z*FcspjE_qgpn|wu(Zk~6okOBx2F4}Cx?FvdQideCv$!B3#p#T5rN$;DbCJZ}Ei62& zbC|^CN*)-OC_&UxiQ2-Xkk+tMLr&UOGbW7s=|} z5`URTuglTs!#OXxrnmTOn%gV>G8QiK^(X53^UBG~64E&Qbk7K{?{6=0NX+Nr8rh*) z(#QYc^H~o*x;XRe5w#{Rf8qTFEA&2TBze@!QZM86oJ%=(#mUi*KBk=05B1lA?IB}L zYK?5hmNfQju5c~tJ$9dw(yuvJO;5?l0eq@SHjuWVV|O3d|r{P zQEvS&!$Q^^1H4jQvku$eYUqEftLrMV|CMn)5n0Bn@cCM}*0bC=AhyCW-hv!fB@_Ew zeZQegRQP`|E~&3C)=2$Ue$6m5J#i}hD%K3^szq^CNtQKEhSKu0NmWy=Ua-82&a1@cD&C!z>GV#`Np;Kkxv3*= zFE24i8X1?o3m>FE7sdvA4!STZKKxBx?s|U9WIem>pLIhAQ%uCy%Ac$CoMzqB~4B(^C0dfi`Ege?`%qs8He|GfVq- zGyStl`*$_{eWm@ms~*qH(*C4S_n%YRpWNvFH<$Jg6MxCmqq=`e9*f)#%MDY0TT1zL zR(?B5`GqUL{iXc6D8Hk+pOm}2JiJrYgD+I?lct`9DtGmZp03d1-^>?Il~Zrs-+YGZ z3VG&CqKkw^x;Y zaS_YU$4QUmZN6%I+r>7}dQEyf=hatN9d^5xozS%Bl>bNlBX4-9=I*=p^n0?|?D_Am z*W2V=#4*SODw7sZeCsSuhCBh7I8y z*a*&pjp2MK^Fwch%mLCC!VtIuwt*{QTeu2#f;U5XKDWYfNIR|8A6*Tl!dL@)!rLM3 zwRQ)@K;REn1xDg(MkHF(_6Z{_}FWR?|yl6ar|91Ej{3rYw?toO%{+$B& z608dMz-sVSSOdNeYr;2SZMYxSf#gN22M@yYU?FS>$%}SABrnm~6Fc!LDe>ffzhu;scg0o=~oCA~LTsRCafFt2TI0`O?#OePV z90QlaYv3~If-52S@~?v2%YO?T2UkPx>AwR`fOkO;ycJP91O64h1<8~D z-;g}{-+?ROK}g>G@4=hk`|xJ?DI{lq^$gz zkh1b;!H=L9{s&HmA44BJ1gApE&_4ry2Cswvg?@M#&W2yWdGJekBm4?3hR5J?NSXUr z!2iLUAZ71g1;2yap`!}VA5!N2U63;O?}0VpURWFMgLUD4SRWpQ4d4eb7#70w;ivEd zco;T;N8v^AIBW*LgBQbJU<>G|s%asxD!ddnhde`n3)lgMK%S+)CF}%4VHbEA>;^A~ zJX3!M$TRhKggsy<$g}l#g?(Um*bnxCk+2Vpf{`#9#=scpgiaU>W8px^JK!G-2g3vy z53hnlU^hZ z2~^{zr$7G}@iyP>`*X?vk|ACGH)Z@#>Ml8E=uq6)1YKy1l7aL>;J30ezR2|T@DIUF zNy{p5!;0j5k&k-oab=d3>4)h4X_*rX@_nu>uQykhQ-_xbpHI9ZS57w4ljg}$AzeO% zSbjT?-wO2Kl#j@{f6>p!d2&4Y6I8mY2hTOac-=XfcxmR?M;L#9O+-PCpuK&EhaTD2 zrAON~D-t%2S$1-H;}+U@ql}8mPU2dOzZ{}-6FQ;1kFl^8902RUfl$hiKD?4Q(EBMl zBLOzTe<*AW6QR_zSHVjleS3dvm<%t2^zr@e;V6hcP#X<9!E0bRbiuAL4MxCpC~`&y z6gh+ErsNA`03}~gUjAtOJ&-hO$OL}UtmVKs=!NkRnZQq4HJ*>3G%ERtG%5K>iG$(QBw_3Ve4aze^k5 zLH{kgs148erR7nHOCO;}ncujCdomuN`{%iRIR#l+de|wY{9Ngxmy$SU=>8yTzAIMc?YXqs$@?23iyHS7 zot-+QT@~3?4%&95-|TL*e?4Fj{=E%4VMESo(^bEMw%jj|S^6IrLFs=;KZCa29|DKK zHjp-6=`p4MaXIHnQ2H6P^{Std0;Q~^A0lO&3cJDKQ2G}mU>`UN_Jh(tiG=h8R6j%d zDbmlNPoUOO8Vl(gseTD*)5dW=6iUB@G^lG-W@;Js{Tnnl>P}}RR2W!#D4zGgf~E(Mz_L02hM|Y;e5#7 zs-ME&s-JQrT!cS;7S&%_0;Ru#)0VETDS?`10RFLq4ccx!Y4T=F8>yI zKYR)jml`wP0H5J}Ba}MgA^035ZvS@pclbOcZl#wcZvP9MZ-zVJ)O{!>heLWfhlA7riB?5jW<@bziX-}&?(1|*cc9j7eZ+do5JDnVmJb} zfFof`cr|PVX|q&&EA3%B&S|^+SHQ8b15AURU^pg7iCKKI{*Da3CyzgW(iN-jv*)1h3_syr}k&JZRT*PMTG_I12jtHwMmvW8n>u zw5j%yG--1=p9tqcd5DXk7cPc*a0w(0s(s|%s(qXWrG1)<+!K$l;8QqewkjrcIiVm zH@igK@GL&Z|Pn-^@Au_a{3fUjh04W!AN9 z{>ky@`2HnBrQ3fQ)0Tt!SslVn(*Dy3=-3ZPcIm!IT=m#3P+v=sIlW`kuEo z^FBH2e4DBm`9rau@CfagQ%D*pvg z`VP(DASmB22eLHTBBcm3Q;^&Pl}>N`k1D1C;(kapNV z1dfJ7;TTBVO7~Bkst+*&j>VsAR3E|xX{VL$Jph zTeaB~wX#E|J@-$=e=?i_^B~o(>SOq!kMmiO_Fc)$g!M1rd>UK`r$Z^%m2>znfQQ6+ z`rp5(ZE`#r*?J9dI^X}Qv%~(kC_{P;An&(6Z!4&ZUifLC22Ln;zKJ|I2d|MUEkDEK zF)tT8+TyxkoChrz;Y;=fveJ~7@(bd(OL3;%uZ-7a>G5V2uX)`B3T``CcO-#iwKj`97VT^KC1cVJ4(bQ!)X0)%^S; zkJ>CK_0J7Z>YuqV70!cF|ICL{|M1N#-P~eWjq^Qo`0orH68GtU|9t+r>3Nfk4#4Sr z|7VH)znP&5`~Q)YnUtGQ`u}0PoV?z~HTw5mi{DD>|4V-JCHwzQ{n}Ff|Kwu7qW=E~ z-H#~)N=#7S^TZ;*^8Nqo)wjDW`o&q>mksWkdt%eB&wkn2^0)Q>kCGQ7k1Ed>axQIk zAx@6xjCXV=lyCb*SQGAoQVuV{+VEen4%`jv!acAad>PhrMkai)uZbGZ_)j7ygp+PkNeB`;T>kYbU9oZ6VmdGpJnXre*HJ! zRIf{QN!0K8F8AaDU56-Xcu)_M;mt<5=++I6#Q$a8pKQs{VMdyaGfF?=-@1QxnlEF5 z6pn=bK=*TJ=lWR6TF-PzIpoP4kwcDM*7%adwtC@3FYd1~_T>GGFrI-?-qL2O zLuB+&9qM+14 z(NOBWL9i*LO;`Po1Q^13B5VbvztS2~H5b_&wd0&NUiCku-$ELdToMLF9+8(p`Y&Cf z^j}D;HWv1P$Q(-E$%Ilzxglv*V|`LrNk2yVBRmFwB+Q0V9$pv=bKwA(4@tY~uMB}x zIhTIOG${R$8IUw9T_$N&{gx5%di<}3H$c*;be19)&EY%^@(k4c$oY`8h<@1bfj7cQ za0w($N;gTGlx~tVDc$5`coV=eS<1P&s-^hR^HG${(GP z=c{;zYzOeGe^d8A)}a@h)X{PXql2hluhr##8bXRdx3RrZ z_oLCxEYiCTB>b1Ey}QU0_n$}FcXa;eg=X_&wr-~4w34UWP+va#)mzqD`C&RqkgBQzGuJJ;2& zk12&e{*Y&J`tm>KW|>p+4E5iiLH}=NNYw)7noaACI)FZlI)thYNHgjH<0|=4ba!{@ z{<4joI)B7C?_!+4Yn)46BH<4i=k!_C`KQLY^bgH`v(zIgs$RIZ@UC_3f_6XT$zS>O zFW2At&2OtmjykAE^!rF(OdZm{EW}@q4t%ddzG1(3CBo|PDp(UH!P-#jhx$wANv9LAgBuVw3(_uT#GazYEdOYej)en|( zm42_3Cw)vM%TvXw{xL;ex$EE@crT>sP&Q{b!VR1+g4F;1CGa8mH~28*-paO&d#kz5 z^3BJSa5?1f)BpY_q~&C?f=3DcpJS}-D-lHOGVX7(^!gt|bA6s{&kV-LLt>CKJ+cPK zsy}l5|Bw!`1M}rScJ3aK-GTq&<-g>R4k@e;-#_y=bda(<=^5F+j=7oXMBx1m5oG&Z z46BZoRq2ybVgy5?V@Q$EH6$w0<%~;;jY$!Yn52~Gc&Gdo6(2uzxGOFtHYqA)Xp&2< zYwwDWO^uCr4T(!05|t7&kYKE=-z6OHs00^l=(~pShg__C^S^WG@MKoX?-s^3Ue1J} z$+1bPaWS#_g-*5AU;o6RYK?qnY-(p&Nnc$mag68@;ZnbNy7Y)pf3SG}utYO(y!xZ~ zPAu@RR^*o(8NT)w0PKMv#W6%}e$YQIGc!FcC&!)HaYE6y@+G?JqjSCaKD}q2?W-t2 zg?)KFV7ezKEzjf5?>MbT1jggVJJ*-}Al4VUY*fvs!}BKdhz!-Z(eeSH`h%Cd9^2`!*G3z zzwqwiYOBAV5xl#V-vY36v?qtnIx@qr_FNItVS?9}EBeHc4nwHlMpR}MC$mAy$j#NL zdw+{)TU>L~h-sH-HG_vWmVQ_a6{@j~2=(tEISZHHYXv_^2PY-b6+`VC9ThX!6`PP6 zm&6VwsdQB2_Z+TItRR5I-^(0d79owJ0j@f(KJMvY^k6-uk2%Z5JWXG&Yl1tC|MW&z z`igyntJ07=G`E`gVeUI{iPlgW-ii)?6?{!SwOp%TsrNI@{_Z{_Eo})aX%RW^G4lAZ zkrvVZ=D4R$z+0t(z7%Q5_snq1*tk>8fswRrmX4p6n^ z(KGldbv@-n+;YCtIG1~wedQ4(I+|w_+AD4?k_&^5y5= z+!3>nI0}1cQU-<6yZSOi3Y#-Wrx4u{2`(YB# z$QXZ8&z0#-=YL;!nZDop-70*W`Tb@s+PVH;SA=%F`0DmE#-Z<2>EGnZarEdldBdeU z8~nS?hzX=+2_0hcb;X2V?jL!>n3oRB88v?D&2+{Kc{hU`uN}R9(KF*N@ATG&r!Lm_ zWJ^K_2y*|0d$8}{v*^zMC)8zxO_{r$WSg`~5E@-M%idu^4TCx+Kv}#8t3C9#tLNVPZ*4~Xt8GEX#+fY^`tRB{ zljo)0pRKKi*Zw4>Tl*pB-Exz2%FBmXLr8ru$(}=-r}T5}ZV`Ub)g3)zfHY5qpPbtC z-YvaCF3kB@>-_N6m17udLih@DM9ka!Si$P0Ym5j2?Z)=v`%}+h2!dKgRc=|`Rwd;0l=~`z>_sMUe8&mNgf8cyi)`l$|V!!ts4Zr<= zZ(x6=!XIciXiTeByBjT=b=k644n_TpZM5<)zXs_}b>II!)cS?LWzHW{yjE>x*Cx$X z@BgN)!SC%mdgA_tfBh<~-|p2TdH>aYdw%`Gp?h|?C*LcX~o=CIjfONm4Ep?MR%z0;=f<^_YeE|srzS4 z+qNUB&6w+vht++nG+26|{;Q#p?{@0ms^9M9J6Ll@g`a*=?o|&rx#oceE9OnRq&Ywq&f8*I5x(<@6$!M4K z_NtbHv2*-FadPn5D_ubdly5p!jXNF+_C}- z;ypVEMkhrj#0+#Lk4%Vh#S9&mfY!#98WlgxmjBgwq#=ju(&=bj1yLlVnyQB!Z%+OM zPp-A<0-Z(0$_@*ihH=;Y%t^&@GB{e=o1c8{yqq*1WSp+rGk$lvr#L-RD!TG4-U9H? zB>x)?QozLjGcNy|_T|-T>AeKHC`#rQiv0g>JthC6aLG&adGkW_46-(7k?fyaBy<0o zOl_`DC31f*@tgAU2b}*={Yfi1Jy7!a5hVxRwjpM~sJ+48ynFPqe>_or_Qz*l9=DRe ztmJend3=adt>kMf z`PWMBwvvmjH3|6ZXaegN$M7zGHx*#B~S>_2041=f`^3T%)4JFy^$OGw62fbxhLn&6B} ziDPhWAf^lPaR~!-ivm~lu(){Vkf@k}aS5?5SD&PmAxUnLvlCLB&Ny@2PB%6P59=JJ zM%a@F#wAJ+WhNnooe(?RmFyg>q8!@4e_TvlRJ|oi5*7whzQ~urff1833S=AKZ5e;)R+`yU0l|Npp=wfR-CqF|6=2b7;nxv z&v<=E-cUN2N{~ueY*$>uWqr@hv43fd0w(xJ8{_huWq^W1`ipW1`_MuBRLSN3d|zg- zUg>GF4O5mkqgSu%i~c5@jDdF}tV8on@Z{@b;0!q!*VaAB7iUMp^&+n) z8R^P0^aV2PAb&DEp+$19uXTMv*>sJ~XV5;)P#=ilU8b9fSp}H<=Urx*PCc$#{2mo7 zL-{|bxSN$rxAZ0SBShI3uq$b~berYrtgVN<7)V)OgzHJVn=&SYokQ7lmn=@pbn4gE zElOu=71w##IrI(guFBu#@=Zwd$(>F6gtEGl5_zbw>`j{qiO-Bpo`-2O5h}*@9DbZU z58;iBHFekXRiwY+B~|&T$Y#RS>4#K4PBHjuPRqiq$?+Fz?C^SBy zb2kZB#;=F&r>{*=(zc=@dl*HNw{_=>OqAngQFEmqO4l05P@J~W$R9G2I)q{a-EyWp zH~-j@8N94ludxyGU*`0jv}{jCNSe<*&EqTa&V^t_6mprm%Vn39d!LM32vokLoF#pd z-bYpXLX$i5_i@|@j3HjE#wy=wGA-!ItA27Uzc_F76$J}ot;hVWbSf=SiUm2QJTSQ1 zvf!v&;y1nK4c*+~Fymy(|EH@O*8gB~7LF{ zMg6s%rahwkKdjNWQMWs5wfA_rQxqr=h zWCR6dLpP@U z&wsG$1v}PdWp?_+mCz0TF^jS!x@)RE0`a!lYQ6q#N2(2?+oIQ`qxzr}%^OI7Z~$$`m_nis>6ubLOb zFuSr-mvgeJ=EpF!tLBBeVL$x+@VDv$7BA!*!tKHx#2v@gT7*slHv+vt3M`}&m+|B* z{+@|jFMhasi^)IEhqDj61Oib4)rchZwCDfP-BMQSt_UuD%1s-B`spA ztrM_y0``0WnUYW>xSFD{Z4dApW^o&JOHpB-R3~$8>IRGkDkC710?zcD08>_8Ac7>v zd|X}JY@8PvEe?N~6AMB5DOq_qGJ!+O zMUmmj8OOM}DT7|6!W1x@@0wGQpOwreIsm!9sk>-wtcNG}D857Kc?W9@-9Re&l&q)V zrVz(oBfqj&M(%_(R~G&vEBl~>8KS04FYxipDg4?Jx%`%Fl;_@h~HGFYsMFlXXf{MX`Hgz#?uQQt*-^jvb3eHLw0 zn)ohMkyKnBzvWqouIW33rhbv4OF8{{8wcVgp5^0%cbwn%K%4jfe%JHQ9Jv)8k(F-8 zYW~pKW}jkZhjO;f+jwWPl>a(c`l^<@>+P@k{LX(rJYm*G>vDf>yQd8*RSk>e;qq+R?9(#_MphRq;#r#}S#4~kCpTNn+$gVH}b0j2Hw0p`LV zp~U$MoC0NiPCu0OIVBxEaC)CmtuvzSA|0a7YLAn{)a~}-dP#@qc2gk31nT;M{H^z& zbek}_UUbKVQwM2N`G|q%;S&o(;9z(ujDynd$hnywy3If9dY*?N@E=gpBj<(ix9ZGyBq0Nk*$-ghROANv zyKU(?TVhxDBW@-)K8Q2tZXM=fe%G?Jz1{j&)^oVzvg1Oxcy_9emJwzNM|d?A7B0a;Me2IIH<@R`cA>Ha(@4zR+rZ zua&;gN-t=o|Fc@R%S!Lwxx2i#P2WzadwJ+vKQ|rv;>W&z2N-y@(vMo{JFWDZR{F~` zt)~o>9??qQd5pSO+9$nD(*N$^D6Nm9XqCQ+a7y1K`Z;OKL_a6j%h;w~r|WgSTwfKx zP@EiMdnxsQB$PHF3hsx2&?}vaK1u8|Z^2pVl*Dec7Kyc5AE;U~i9H4V(lqo)D}N_l zQefqOPku=S!0E{U_u2M;w)}6)|Mq%78Ei;W(Ly@5{BO(um0uUQsDTQI0)XcHOzQv` zGu0yL^!!olT3X2$=lVK9y_I~r<>9O9-umq57US;8ynV&Js~E_%>i=8G3s&|xmF>@4 z$wx;SWDar!rA~Bz*#CxVhhE-MbxG^+eCu_7t>hFdJwWIni9h`7HmgP_K9dvI%3Y=L z(oU}gZjPGOdPY|A>E(3lE3%8Rk~^&QGgkHvpEAH5SrUq3P7@fKe%JfwZY z+M->>Upx5Xw~y`dTz>8J*LU52cvEB6`HU3*b9epUK*@dQx_)La^{6lDx66uF^5IJ7 zsoNZgY`7gAkI0A3abs~6ts{G?aw1u>54!|Ts{{fq|J&pL5wdgQ==?In_kmgm*q;B# z%ty8vV#gr0E0Mh>ki8#}J^wEtYXbd$82|U=>kU*u#Q!rb`bAMJFEf_bBP5U_Hy6>37W;MS~Yzbt{Mvl8wdg`kAT;eA-4SSTItnX4h z->y*k)l_kRO5A2z&7FWGe+{{Il?r#6N*BX39I{W9tVE!v>qld*o=UR%T_2Y+{xs$( zmY%C8>-^LsfRv41GWz^I$$#1TdlFXiE@fhth|KAeG?$&zC;pNiNoR2?_4$v-@yo4# z_UU>mt5XP+ZpdoRi! zm9Fz#*9{$`-u2`3b`hP7oI6U-X`)I{`y5Y!(xy&_QisogVz)38%G{ajVG^7LT~Oxw zq`|q6=2h(nybLbq{4RJCl=gfT`~U{RmceR{OepPSW#`G9ioVLqreQR5bj&@FWZumF z-^r$dVzdvt1nd$xg%Sv?{x3V-=bf4nh<(89`9Eb8h{itPw*Jr7|B2?)-Va<^1=;(7 z$)f6kSrh#KgZ|HGpaP=)JL9%Lrv7iVq5o^_kohg>q2RUXn&wQ?^?!P%l=@HU^Cr`% zvwqjq3<-;lOmuAbsIYxlKdhuia9WTgjeTtW|cLfxl7qCs`S>-s@S(*fnblKadrr4Jm8(B(h_ zDru@{{VloHI7;dCq&%cFWZyH<=}CSup;70O56M>!PIPmU_OkjttM$2L-|^-uO`3My zh5A0^3rn1rT)!(s9vnwg94bDI;M!mK?=}^Fmi`Fw6CG#C=O=kB`1$}4 zd%vA(nMfW?y`sjgVtn_p{qr{e{{9fUIls@iGlnOzP-Z}41 zxM7L=_3)M-Jy>;7XKb&m)}XP{`&ijnS=oG9%^|azb7Q4ntL$7HD_gBUN*`yXw+)n@ z&PpG5uISOM^!`?Bds*q_t=9aq(#!u*wyuHFlLpFW_89HK7M$MB>+OCbZNIcp8*y^T zoGNKrdO&GYm|o;>4kIDck<=Wiwvg$kYAqfg?8te4*b~M-i=t ze=6y}4t@YnrU#YvfMhRsb4{RA-P7Gl|9L9&x+|#%|Jn2Z?D>D*>}+pNsSW>(h56%heC|A3|EFPVt&Qt7nzf|wxe^|-ER`Twv2vV%k^TM6uhkTHD{pxE!Pk3{y#Tl;Q!C546OXm;J%rW&;%v1;CkJ|3}9EWjz?H@qerJMXc7P zu$t%4B2tY@ufO#+$IJ$sU%fG+QxE@uTUcud!{8vt6T@q_oHY0CZm(8(dFSfTHLM{p zO8GB3FR1&zf42UtUf~T-Kkhut;s*UxJZElCnX_%3i7`wZVlCOlwJ**XzwydtKLoYO zXtVVp)&Np=1P9s;8q;dk?ncXIUAF9%Ls36#nw4F^A0_{v>2dzb&g-zU3$U_Vv9b%W z8vl>Oz&*(Ewf0fYi%WirK2q4W{nm-y=Tu()w;JcS(hFGWS*+%P1ZwSQt8soSdjuhg|}t zN+7WEKfC{Uv(xSIe|!Aj9{;z;|Krng#z!T_$?iQ_1)1)U4sp7bc3JcF)R+{nH!I&N zoW1{#ZT}yr@qeR%3W)gsyRHABCiv274`ZxY)~gWCVzTU4Oum)%fAvhc@?`}OS)12K zqt5yt*c7FvWfiztb3$JOq`_G6f0^}mt7|P;X`&aiZOt`w8>Go^wba@gwYZ0@Ly@cE z$;@ZiTE)=>{;cjf(9w;RL~daw?*>+~Xv(_6_4rLsPj$ya?IP`Qt(o?vTGzu|HzeOP z!yT6sJ>BP)wKrs~5t;8>ZLHik+ObU2*CdhrsWmX5Lz^l~ypL)1wZ+6;ybj3)%73p`MZ1gn*3C+-MY2@=R=gHT*|mwy zbyxH_YB{QCPiZe|t@P(Zx->1*J+2_%oylL98s(>l?d+(=(`m_pCCog5GuX!TRQl6xQlXy^FXeFPBtYIu=IT@#yy1pKY zl;Nqahf;FQWHWcNM#_n?@+>v&oyL-$p21DjyT%%roR?f9Wo2Cgaa@d(IpNK4vq?aI z6@Hfan(Jk#-p%5in(L&LeQ(XRQsh05JhRSCsrOKRujri47 z(kWQ!M67fTmDMR&=?<)P7FISye^olN?w^I+yrNUJF9*E-Q?-3xeDWM)=AA_s^V-qt z7dry|{G%Fe2N>;bhjaunIt#qB0)rnZ?Qmu5LmDQyNYOabSQp!1g z-1RGNy?#gVt=pdYWcBhxgII5&pZI62?YuqXoz%j2;~(o5y64r$Sbsr1m+5hBZ(Fjq z^R+7m&&+MRbv@6}YAutqO($!mt2$S7vTv*Bb@}3_#s&2`IWHkrp zT+!iL%?Yy7%?;=+@8^}(7EU=duEYMWN0L^|U6r$%dPDg)zG(Jc?i*`wSn5godtA-) z+S6t!{|makcF&jHet2ZXUEg-zTy@Tqnr5X7mbFQ0(J1MC7QIik9luL(KjP%*!CE9t z_t97<#V>6UxA0#I`@&Ed31wN27}yD7O6CuTd|rOmPf=^AjDSNq&xBV&rT}Wma0VO( z=fdmYQYdRj-v<}K^>7s22*<#^@EZ6!91H&q)8YG&xc$c={VIPm@-z!x3TMMm$UXdR zAfK_n8)PbzKNhm|m|xaoxfV)!gyHnIR&Rs1b6yoEd6k1Ssr@G$(Xy3vw4 z)=rXI)dh)Z=)9K;s8o<-B|FQS~w(Wmx`ybo>$F~28vF(2X zXa7^wKm|qvDE-Bn!NZguBW7rlD>XJLIc{izYe>`}ISZHHYXv`v;w&Z66%!R79~~7l z*u~7hxFkZQB5TR-Ib5GuK>%r!BeVvpZLTK@Fb?{TYQLFWSn>BMSro#;sD3v!)L>GnhyCpTHC;%cL{K>K3qO-#L(L(5RxV3pLD_*5K|iu^@i zVx?~@xv$s1)O~8GdsMWJFVUDsDcx3CJ(Q{2lDtSxME?{df8+Gjif&NXYl)wpQeCel z_bt0Om*`#0HJ29~rEjMon$!8eIFtb15f&*gvHH+_BdBAS=0dL8QdfFMm^)U3Y|CG5Ex+o7OIy ziVoLGe^FUIMWFObZ>w~ky4?FLg%;#E^3WUJ#mC-#>$SH&sj=pphwcuXUa7LSOM%iu zS?STN*5)s+R?>V_S;^7>8a*!xI4&voiMC~oGn)tc14drAK*3(@r* zRo_di12Z1FC1U@MBb^r4x%Sw$o3V3JdcgmF+223x=cn$UF>Tw9s5WD+XU{_wPn8Bs z57d7(H1gd}-COnBoqUI;S*__~rQfmA<5=lytZV?S^gbuk@9;_+?W5jqhM?=9YSp^p zsqSyQSy6qBANxjGh!b!a7YW&hpU;^sj1p}cM zDZ8djMeE7j(o)k7qn!E;#EE`dL12?SRE zmz}O}uk1~qNO7Hx{?DHOXY2oL{hzJ>v-N+r{;xye^nYdp6%h4bL#W7^rt1>*u+@K62i8!lp~@?`L>#(Jn6CE>GxTtxXJeTS*>^-+OgUxf zX~}o{lA~jibsNABm0zxphwLF(QCjq{HPpGtcODfksa)EOY|Eue?bkF6+ua-AN2sYAjHz@wIy!ONsSbJ3d; zt;)OH)xn)azxe6*zx-nAami7}1a%L+?0-`C|DJo^i;D_w$ZxIGwe1{DwLK~=6Gc$f z^3zk@Oxehj_?^K&{`|`?k_P>^g4|NS{aErhR(UXfRM-8a|F%SwrJDJR5hv*sJ!o?g zkd326InSzsUmdMiFwy_gn6Jnz^Cl(ATy(gSUnv{2WW?@H(kp2#&V{bq{gKGTzc>em zKj{?z;?(Q<;U9@x(r%_)Y!p9LWvFR?!(X0xgcd{zvY&N5JrnDI{3%>YnBf$%*y6eh zax>F>ZuJhzBUJixRo1yad57iukYbvs!p~OELf#8BJw@-W*pAA3ah(ctJ^TGM&~njS zNLd$BPO3cR6627|m!hw!qD89rR?2gqDo@E@_2BPSJX&acLg#R~MEs5w`=LqF{k|;r z>rsJUXVXtlmx@oRQsntax+EWFE~E?})#KBKlNmXGr^I>5??~3rkz*!KK6kN=k^1Hb z6@J!uzHwEJ#w1EQv2W)0vUQG>mmYrRNyi}MA*KQ-uWAp-zA*)4GvL-nKwSym#2Q0=~R!P64Ud|;=>YP-{bN^hWPt#WL zfaLrq;3jT20Gy`y@mBCBI3U zDyp00IlQ6bKTN#(J2X|D&vx|HdZ>5eAlI7jPw^KoWfY}srf*Q;r#bpK>QlGt-z%j- zUiJ2=7w^AA8(FG83zZ}qhty|}mZ{J7a8Id5rSAGlT`%=dcu_s|Qn6ozL?hw;QS8^f zykD21YfFUdCgD!@4oJC4d77mu&sWOB$GxP6H=n>i$>*v$nw!oO~_YINc=IdQGrRT?ktg#D`3_)ko%gkKf^-LUIdOq|(rQU`5E*GJ}K z@7h=Vec`*)x4r9FuzhIf-C@_%e-)j4nD~#3@hA0Mncj5%_jQ-uv}qn;t;Wr)?AWcw zVM3-z{E7d%_x#(}J@Lz>OZI)egP9qw12@ z;rS=Glb=Q#q095SPC)GDr9YB|lOqnLfN&6O1V=)eB<*S_{fSiA+&GsuE17eKDAn%_ zQEJ$rD?54#-;VPkP;?G*ehiMl=`y^sbys%#(ua-5$uWs=q8rGCa=&X~IJ^!z;q_4L z@%>QZng!D!^16yYg#73-IC2z!Oa5B&yX<2s$8y3+yldcP@J<*3*TQJH4kp8UAVc%o zy>PnWKO1h~{2ury+zB6t|AkM(BXBGH9zFwqfzLuo!**C7{u4HY&qGP;3sCI)cfxj1 z;^_!?!3ek?4umg57km|F!oAP~UxztxAIyhu!fEhrI0MS{l%2K*icaGIl;^M(r^~sz z+$(96F3C!q9A6Sn-iu?9F0J-8l;_*13iA(O6L>ki2+H$m4!gpOVJ~=`@KT=N!2a+A zOo6{Z#2l>};qqWzDCJrYE`$x>Y8VV9oqn7y3+ghZq*FvpA5M;@#3yoQbJz%844cB1 zumx-d@RcIQ*FNS?~y436DW} z-@b)g;P;TOllCLT#zET&KZh?tdEZ`vlD5}i5PTiV`z7ZxZ$y44k1Bi&{5R(r@Ew>3 z--FZP`;c!<`w7m0a=!&o?tc?>RMq^q!zyqctPUT6wcsXL2X2P-;FGWcd!yLE`df|5HgS%h> z+zY3`{ctM$2u_1v8t0PF>74%zXF$oLoY#fd!X|JgAOg)79>TFy6%bK*wh zrs0<2KA?U3t+qHpW2wJLd|RB=+@zTy%uT`-hSOHHBwe_&_BfByFf^hvH0^Q<`FlHl zdvRHzyz{L|BW^4%7q=xMnIelDm0bWSGjmc!-bLH`rY75C{{bBP*BhsRjQpSZvH0V(%WJD!>t(I< zsb^YmdjC|>AEd^_#gB;ku;BhSw|SNgyVXfwe5m*bXS9E#_13SSnDBUuuNNNDzOmMu zTIpXayZ(oj{>Dmgx*$^0S$;l@)p{XYRQMbA?V9xNeT^F?O>6!Aybgs34K0-a`qN%B zd1sWQ=jw<$2Os|C+lX3gn$%s@spl--uYTh1nRnCY;hjbV(^6Ro@Ng1=E`5#+OQJyTj z1_oKRk3U%n1X}*jPRq6B|1zfgw*2o>ngLIj9uew~gcR4XL{nK1ul^|3G$f>;X9%-x z|83iU+xFj<{{t%jOXGBo$p5AdU|SjJ<_N)|4p8GLPX}w-LI$M7-gsP|+nt8L*yB~D zF?VRLA?|E%-gNv-d%NW->;+hR{o1+|A%c~}D6mG4XQ5l+%5Yk06WF~bD9g}a$1`Ax>&99q0L zBTbpFsr1UNWK9wMx6G-;+MoFn`FN|}WgJhgZNeW8Eh{%UFN3@4zcn&`lY3(?oH2nP z`Ln283RQZms&kU1J*UoFt9Z$didSC)IV;!c&i6^gl3uZ8kb4%zD?gTq_c{9N4lD>H zY)I*_=9~`oTWG1@(qr@T#1damdt0d1QV|c$lapRBZk$V&uI0?MA#b7XBk7M;HpiE$ zbFV|vHo2O9-Bh{Iokx0g+e?wR9IQiJj}(Yq?Qv`u+bF+D*vrOXQ&F`jZ_3JXN?Ml0 zWZDyds=^LrjhF_S6N_`X_jkncxhlK+9g=4K-rfSAd2=JpytZ2NSh;^tQG7Mk`AlMK ztX)QYX1QYVp`KSvj!)%Ru6p; zMO$(Ta^+gn&a>>gGN!GsymRK;C}HKE;#cx56n}Zo(*lpZz&eA|Q~WR_ZSu?{ z4(wRf6BfJFX6o5uH^a*>=Qox)zt=dw+4%jvGUracoHg_J4C7qZeU|#8mtog@@H}qJ z(H|$(8_}rxW0?xi9Evja2S2O#;%ulpD6rgx~*Sdx;FWz#`|A>|IOB#)*54+Ajdmx*E})r zk@-n?jJpH;tpuISN^(S8lY>2i&xYZSzvUnOaRfJt4+#x=y*I z4pY}>$Du@Ypp_MUw&=wr9g~#bfTH^$ofc`&P2G8G6=qS1FuEqRGuNBrCQDS9hULP9 zt1!CW`>1*juPB|g^qI{=%27Yc>!d|5D`Cs(oyA|S({;?nPe%Nu>?_hSOMazHOX`@V ztmQeBdITm%o35bRkV)Ixv0~vK22ojCVRcZK6`${ z=G^zc{``~o#wXf3-H1*-`~z-b&8H|SpC^XbZaHc0+udHR^778rp=(goj8guK&I{_k z@1Lzdt5U6!YiVl{)*W*NII|nBR(;WN_Aw&EAi(oPo9c~J22VF1;j)kc(1FnR0RQ%{y zmF|`*L>tff{m={1pGsSzbg)z4Yn)RB`=#%UT}+Vxc_I)l(f9@`tG0h`u`<2O10+z*kb_p7=XU^g)uR{c%FMqir1T!FLU9u z3Nqbgr^!#rsA!hF?mIfomz6!PcxL?+RDlPdHPuVxTxyt9x%SmG}C$3ah?KJ?phlg~Sn%T8yM3}+OiVtrY&ux2q_#QQ&q>wI%hIJV0<^xJI+!|!sfcNJ^2~@DUCC~i(XQnE8xy4 z$jVZBe~IST){7M#u!NIq^(#y3bhjB}6|9q{<^@~=*IvkaRz_N|>(6rKxpTdFzHw;< zS%_$cz7smM9B2CYfnM*V7_`&64!#loe^b}iR_hMSy_=GD(T_W@!j7Gm;m-AWygB+M zMdKG0hB0Ohhz?eC=@LfDp3*mCNpfd+^D^;~Fdwjnyp)sNOIb> z&W{i7NyIT`Yv;V;itZY5)6Mc4QDs0l0PyCv^U0bzKj z<2^ZUb&b5sa*ghvo5V|yH^rT)ev@~g?6=1!W*#idrav!9m)x^-iY2Z3vowAyO09ga z@*GWnNu~HnS|lBM>h$X+4dPdvGQGSXH_Cer7fJbVGtS!?K-3=aOIfj-rjZ8Ck}2l=nssX;-2- z`AUWNmw%4zLSXJyQuZBI5$OM^vN6YQa(O}Q^+Y~?z3v9qf>k>FE(dekKDcf7{E36I zs@+~C_#dpns{GH~ey~>SuAgn|gWNMsbokx>vAKD~o`&_FpY9m>)%|G$c_+igKQeSv zzjpt=Yv=pJPfSXy@;M6QK&|UxwI2Q-weHfMu9DyX9Qgd3P6sa;+w}6<3miFn=*(HI z?`<`|q!0s#AjfM*uV3`cxXU}ewc)9Yd#+2xaM+#~^83sS3Dnq)BT}B@sqfc)jCwc> zr^^L;z224v%j_#jH66*=hP2%byZS|rh=y{V*wO2Kc(n$yCf6}UQDjHIj&O}RzYmH( z<1lKy=LezK&2NMw;A8L_xEV@6`*Db^z4ipmg-^mMa0?WB`lsM*DE9CR;a12vjJ6Hl z0-u3*!e=4()}Dhh2DBYM1b4zm;fwGki1WV=k3v}o`72lm$)j2i`G1h#wC~{e5a+K+ z-hYOT;4iQlbYKTB<Vz3*Z_U3U7yUJ=K`eKhpb4 za(xZ_dgJ66OE`HReCBFh+zC+PkufeQZ_3VpA*5fb;tS(%y`AQn@pswhJB@I7t1&QX z*Jp4p`9Im3Mb&O%-P=0ki3=9gWv(VSmi?LvN$AFg%(Y0Rye=-iMsBTe{I6uaSzd;a z;rhBoCD+FF)3(Vz)!X3~C^r1E9`0u9I2pf6#FbhDw_E9TaOYe`Se(|DcN#YhXO3I7 zCB5;uTuC?XQQSV9eNf>}q z+xq`fN^x8N&jbg14dCBZ|8F!nX^iNgPo_veY139#DO20)n&WNjx(#iSg6rdN) zDae+neQwcviXMzhjBs5}K@V1=R66QtHG<`y4Y_Ay{+4^N$7`v3hh%j2d38|57qVdim@7-2Ny6 z2FFJF{2>N!=lN~b%ipDcNUkgiBYIQ)eIixvv~2N{_eIL?Lta`3JMKtcw=*tqL|s3l zuK9fAT79m`IB#CIS|*Bd2jf~5c3#~o)!P3bd*=aIMX~kqy`hDk2qGX#sDcs*p(7|+ zH@Qg|AR3az zJ%YJL@6G(Ux`*;6ldP{A%YCh>c3*PcOu5XOt=@8nlit}|?p@lje&^ASta#@UQ?0yk zIe%TFFsr=L2=WqH^f8s!-k@U(>(u?^Z!p zboBeVoAl(|Jt_^`P!(y&bKK84wH5-uUccihwas7g4I34@x=LBDv{nYUwk~PhQ`w*L zl3w-o6K&W>Ti#K5r{Yu{eA%Rt^;Q$fYn@#V{rs2;%E?!AK_}YJXRNB{&l{#-x#_X` z!PXbl*Q^Gav}wKG=p+Pw*-KcS_lKm_RHdKU)bGBtN<4GqvrJu#3SCjH?3M9~itQIm zrL~!O$EmbZ{L+$%M*S_5_eAa~rH|zQOTCs>2dgi;>8z~R#d^5jvDWkTdZ_0i?Q?K{ ziIdMaX0WQiy``_OgvG}kmx*JP_}Zc*PJovxHbp3zIh zalYl2HC35_bKV27?Ja#-d;59yi4cF|2JNhsuI53@t*t>lgQRRYdf?qBJWve-7XBQK3?I+f zJ$$6f+zS7Q(EHUrmhhpk%&W7y$8lJ^J4waSYxPR_SXIWkRHboceReXhUztZf^{Kys z>FWHxhVh&);N6lqx*f_M%DSBoRL{AU>Z3&m0hULdlUsX5m0^_1|5p7R3gv~9wzHTz zlRAK6;{B&9%vRHn)QkQm5Nw63=P-&k6r=hr2^*`z?hD$2mU@A!3*VNQ&{l*?){*Mm zE^D^cU0oyZn1qi};ok;LM-$^;)-geHA977FyCpi`AiUOa)kY(OnzHNNiGJxusqm+Q zf~{v=U%HyHhgf%YPr41}=1oQdyyIoa0 z^H_C$tQt45M_R=p<3;#h87d8}_aX1RGa{3*qtuIxwVaWbj05r3 zScmH92*~^AjFNhzt0et&#lUaqP`A4va_G=ukIPgZ%_J+<7ge9sSazw)u?Zgsh(zm_yAdvTq%^cNED^xRSp z(w|EGI=!rvP5Mr|Y<7>T)0O^F!Yg}Gov!qW(pNe?rKBr;oQ|uFq>4U{^k)*L>&WTp zs+LXnZaPf*7`b=dlc9Ssk3lV>U4TKWEZ`T9zEoaf_wk>ozb zCZ&8kD!&{$U-=eDIi0VD=$rhc+r8!JE&O8pH*me2@2T5=#racg|0etV*lOn!{mwi3 z2z-dFF${DXC5DR zOH1!v&F*Zl#cVgwH2+`Q`C-%i^Pgp39+REBqrETBt5Nd2YOYx{?dRfB@sE5ScscWO zA+Fnouljh}rZX0Qo|gAi)Ym^PH|yh=_E-9&?fY}I_xH(G@6qxDqZ_x`aoWSro&47J z;lAE4ne}u&Ns@YgZFBRTPk;K=J1u*@d+DPuM?S~5TGjvkn?m1w>B|GRUUJ!25hHh8 zH;K7r#%Cd}nrm21YgJAAcqfdJbiT3PDSC40PoqBD*Q3{_>4VN^o_VB%fAU4VZ~V_2 zZ#{d?=B?4)&stzvg-po9?SJQywWw=;8@#v#igvW<8+V?&I?{{Z0l>^Q4x=<%&*R_P;L_@eOE1LMF3U^3VclzTyl@@0b1Rz8vA zTY#lt2q@*rYvk~Gn&*@9e2mK^T#l#e>HT+ifMNJQ277@sg7tpaLG|?--1?yCOEdz- zwqh?(>=yP0Wq;v5;F;i5a2B`>ybinqTnklRS;gUuo(w(*Mu0DX z1HhNS)4*526z~mj0=OGI6Wj|<0pABp!Cyf3Viv_$p9ma5AbToX^}*F(LvStF1l$OY z10M&I!0liN_zZXq$X?r4E08_4tz*G=!Q;S>!FJ#mU;_9ZI2Qab*bQt1xpxxC9@%37!wG2QLISgBOF(fR}(T zfM;=iFk{)jH>7^ShrrI@(_jzq8E^==6O03&2h+hRT$c;xf@NT9!p{Yd1~7q z5g^annhb6N-Qc6(6!0l98+;3ta{LJ13{rR2Kfu1=MsNW5FgOz21V)3efYhP&Dwqzw z4pJs-59k3u2Srzv@uBY=5NgzS0oVv!2?m2Vf{np-AY`KN4zL;ccQ6PfPpcmI7#IR> z1ErilfW?i_vtsNy6Kn^b%lWS0ad%#!0hr!oDo}IN9+ylM|eq{SU1K+{_AFvte z9soOn@q9CSf>Xd#Krh$_qzqPHa3wehycQe`t^2|NRQ3_KHj z9F%(71G@2l0Oo=}gVVrPe5m=J`Az_*gPlS0^2z=g>%rdO8(@ae9w|V zCX9R&!LHyW@MJIxj0Q`NtPf5D8-w{^OHjVU$AAT3Yp@7x2Nr|v!7^|- z=mitOa&R0t2TTTYc#h*i+Key5_Gf|~{JG#Xa4MJwP6zYBa&S6G-)7AK7l8%f`L=&C zScrcGxR`v_f|r7Kg3M$3?guXeH-eXgn?UN&_b5mm`nG{9!0q5F@M-XB@I~+%a1VGR z_$_!dNS|rl0*28c-wuud?*!ApyTKChesB@E0lXO81pW==S@_n2Tfpt$O3M8d_z3>z zL7tKCMeuR(1MqF|0QfF=VpH}!1y2G$0wckX!J(k^e_7xl`s=g7!QdGBqphj5jitO- z;EHqTPgbFehzq_79XwnFE*6)8E5P}1D{%MXp2kJQv#&hvQ2Kg@($(ABgKzAK^ba`M z%l=-<;OOZsVO%P9Cw8Z3eZAdbeD^vbCr0W$?VB-PtG=&&dWTB=z1zBI9lkMLwGLm0 zZd#9T3RvA1#k?rSQs@ls>rNhwKld^I%{YmE26r&MKC35n&HdNE+OooMfurtffbO!+ z_5bt^fPwY@f%X3r6O#I|@Hb!sIH3QRTVq{+K>shG|M$OM|F6}S>S!0h!>#{6#%dJ$ zNL%Tv)6(5~c9Hol9p;j-l(^KGI5m~WT!{`3lJNM%=+Ru|gw>O?1*0$(9t8d-f z3=Pb;EbSIq#&hAD9GGw6y9YlI;%d`w(OS>NjqhBRpL$+|p$Uuho=Qc|4 zFT<_FZNTls?Zf?uYkLj6hq(CvzuX61>`^<8hWuYC;&Xi5(Gh-5a$7RG>Ifc1aIL5+?iVKRT6^Df zKb${hxViioor_Bi3y&K^NZc6WjxLnoMER2z7M`AhnX23xWpZa1ak|G@gc1d}bjfczhj|9>C(zpQR{0Sd_f%%Rew|9_PKMQJC*)%=3~d%y0` zEI2x;W9zrG7El)f`Tx*+cLe1BfWGBLXANI-_l85;KMUwv{x$S1!;V1y9}|%8={bI% zqi*GYSqPF-7?}SL$o~`i2IPO%5eDr4qy*&uoXmjz|38TRf2V`069YhplmF{tZau02 zd!$8)teKs4_x9#*udkPNp!CT_pWnEQ^&Kkw$k%?E<`7MDh27Mg&Ko^e|Kq~HUzB>o zl$$mmpFO~5S*E$#Z7TjJcXxZ@@?8HheqSXk_n3YC1BvU9W>1mo7PY+QR%PW(C~&21~ll<>GQ9xWj|~`)3TD)TC@!7!|=Qr zzOQbaw0VBFcW&-rww*ms#m`yOcT3J26ZY*%d|*J=r=NR(=dRj=H*!bz<~^>(Tax?k zh?v}*HFZw;wJH--qsjNhiUyZ>wp|pJ_kW+O7pOts(BH%75E!*IetG*K+-H7d!jQ zZnvuH-tU`TcRKWr{=DeU&kI9;9w$2U)pg|^JGY`IFE(zg>%{x(!XHWxo?8hVff}f@ z8mM#mzo?P`_$~AQe+$h2=VbaXASm>@i?gR^=9H8u6s7vqbT-V2b&nergJy!Ddt7vi zJ2n9g&~yoiNlnM*to%Z=GkKyrAw4cNIz2hn9gAE#+MO6TAuiE9E+K7Pbb8DfqN&+> zf}@k%(MhDo54l(e^EWnmV%qSCIRhe4n}|(HPK!&OkPs86FN{@s{_!cv!{uabTtNO$ zm=KWvi>5^feLNB-9xRGkn2^uhrSpy198;c-9Ye;IlGw=c5ihLSmIasb)$ zl#F%Um7lLz@j~?3|CzY3+w7L-AAJtsuPW=CWW?I;TNK~`{+JwqiMuk{;R)6WkNxQq$OI8x|vCKtyCj-v~*|oi-*RMWQHPL;{lH zCc4vNPg6-I$HyncBw!d=rK~a^6_*~Ze#B=;itd!ufUuvK6%h8zvkU$#!hTqILY2*! zinC^9CKR#WscP`799g{)7Jf#~P__4j+pB(KK{_p`7<_EVeqME*7*Kk|(H zQ^LaYioGRS-kiL!@Ntls!f<9-ET%fr&Z(j&sv`maaPoZ%*3W;(+-`hyYD#Ky4E7v@ zLp#x_ri`D+u3v{=Kkw{c{$V5Ofw3j0LD`+$-qx~CXa3D)`P`nOoZ?(huDhtbpg^J= zZm(srjhv>g#qJ~P`^DC=lb5rfkds$K(%VK}XV`hUS-_TFP!?TKP@E%q$zBOtInN$C zB{5kA1*5WZW=Oc$dk+Q=R~E7PEb$}_{}iN*I!|nWQHN4SXFu^+yKqdUW8GfcylgC9?jedQ=R>5!NT#4{w8uNaJ|X)DPz9D(UE8@vd1VY_A3n?} zD!bAJcHK#OQqBdoU+Pl)OKtylyWG9){j%9$9h~d8+TB5FRA#l7kj?9#GA`~uxAbBXRjxGVn;&P z)8{JQ71mg5M8z`}oBnTc9}<^lkxz84*ZVTWA1~p}R9wkV+5_2D99(97NrePiQL28M zSVKd1VFO$qmDt(8NL{aNS)F5<0#kGT#e^!Nmh{~^| z!mmv8t2mWmgH)X9m2spAs<6S8VQ36UUbq#LsVAqF^2fz2GDqhPP_f-8I_s?^) z7~$pUgRZ({FZeil9zBCV2`ogop z>j>MR;!B?*Uv%?3@y&_S9!99Pwn(+dywg0TMV^9wk%Z~J*0!s(>a*jFtH!%?uKrGQO*BjHGgAOCf+wY{v_M)d|$k_->I9+ZNF1@tE>5Mujc)a!e5q7jKg*;F2uDe@%!-$mQSD8X-2rUwg2DY zElu`;OzR0v^BN}II+G5aN$1g|LuaxJ?~0Q9s;P@=(gmxn&R0j3eobE2v>%2^*K(vv zr=~9L1{GdY_syi^X3}M=tN9d@?xaaa(ljsdAU!~ctKaUT9(Qcsanba#1@*5F3Vp2Z zbQ?`N!X}+TlP;ub-q19!VbWnV=_Z@()0lK5O*)2!!=*lJ?w4TF`8DY>|Lasq=Z>6r z&Y5)ar;9e8Te5a>%8SjhJ*?87Q`moW;k6NY`)>R>W7>=V+-jaDolkEW;+mV#!%lb>I`nBLxG-^jGTi)sGR zquQk83%7G2egbkGtaJVDAN=Ut55h=Q0kApEPMiTVP0{AYN3GM^4!S_Ka z|EJ&#@G}s~!1@}L^6v-dfZu{ro-sHrA6e{0sLLbmNa{+CCPBKLGzFzR%|Iz{a}e>% zY6;5o4FM&+!7fMk(Xx=-Usu9=5iUnB;>q(H1j_Rp3^JUuhJfOI(%1xr-SnR z(!qPd@!&(?MDTHty*qq6z_Y*?z{%ii;1qB#m;-(b=7K+h)4*Wvc?Q@LECP=MCB61w z2G|9Zc-_G~Q0i|APRkuy9+CQ!_dXpb2YZ9~2(m5(dV`9qyS~ie;q@C3#Tn_G4eIH%~L-4-@wgz7Y<$1pXb^v*<>iNBn zU!L0@a0s{;WEg9`3#Nhl!1>?@;6>mk;977$xD7l2O8qjBR`u!v-^UvSegoD68&I|; zU^5WsYXKeuo&vT8!@&+9-x!NJ_3=%ydVo{Go?rn;T;ELaL=ar zBYOTTVyo)N2a0F`La5Ye$2)}*)zs#HKDVpWK?q5EF zzsBxgVE+FgO8+t?9hmR3GdowR;&(NAoVje8QK^1v)#OkIq)pW09QT;@gx1eyU znhq`~_cP}26eBSIpIH)^|5thdLk6N%Gds8ckb$fP0*}zhU!BbVJ3UbyP5;A%Hwqn( zkQBrg+o_KF5bLbQiZ4>+zS_Vp>A&kyjuD|tTgh22F=CH@O4{tZ?)W*=qmdfB6zk)_I0WWDFq`6sQL$hrEwzsQ94;gflEnG;&6$`~SZ zQT^pywJ;GgC{;scM^NM!6Ax(OiA;RZ(dPT=iq|&TKrr!oCjQREyP4)2O!EgOp3Y<= zVq3Jxp*7c@*Omw05GCo<d^Db;ZA%_)62h!KV47 z#j2ibuKhR7Gnsf^)4Y*sKBl(wMjcf-YtHwWc=p=P_x!+jDa7TzXz1?XH!oY%@jza@ z-hZLC^Jk`cG86A_;`dGSC8l|uMf0Wn|31F!_fNgi|7_1aaWS9#{MA3%3zqM5i0jC0 zwwUH)gkKUaMfXQ=CHQ;reLfNV5huquco)I(pzvE0z?R^dp!6khnTlV6yYh9#Ujzz; z0T=6o#-LZRe9|evX(@iN927o~{!8&+bHOw4p94+-xn*BIcrM5}>jH2wcp-QxDDkfZ z;RJoxgM|6kftP`|f-AxMz^lOrK#BJtcn!D#TnIi6o(Db!E&`teC7*fVur+XaIPVpd z8FYB0)>KLloNz`<2zPiR;f!QIMX?9r@IyU1!_DA^b9kpXcK@v@0r@|(AU`{&(A&EtH=A7pihsqf0rv8Wfc&pC@dNt*0r?*a zq6WcHR9sY+mtUea)elBp)Rxn*1^Kev8I@_~<~s7d9n2|Id5f}GTvAnM{!g*kzj~qn zD*FG(|EeeYqsspSt(Hjn%;7Yazv$pH#zO7Gx*FWcplKE3QkS)`B&)Q{<7U5_g8U+n z#1lPHk;PrIiA|X|s}vz#^shza*VnYJ-~e2fRDnJ(nROW{*EO%uOBJp_r$s!Z|Mqq| zcc{DzTtlsstcI=_E6Js=5xHLS_p1Ei4fJJ-V>pI$H>&HdaGlQR@JZ`Im5Rl)+KQm_i+dxQIJ)ZC)Y)XO1fDiq}*3oUeXmVB21!LIqJNOTb@z*X1G>a zkLbMg`Qnnfl9^7YHDSF~I{%@(_59-H7tJg$_DbcputtUch(7vbD!pQtKkwnJ9k^AU zo9`0NL-KZxVCM&8#2|hjV>MKD+sf}bIl8RE&*@wBeEJO{fvRhZP9)U#8|lAie6 zN{C&Da;=n?CSW;t;jb?m)>Id26CiDCBTl%b2-OZ23b&++p`MS5TA8-ouhji&756yx zEccU_#FesA|9b#dzIezq<647eo)2H`p$k_lG4dm#kA{K z){{t?oajyCT_~a^_jR<69;JGVE3at5#l;? zc2D8CO2r}W=$NdiBqjDCv4(=O1G#rA9pqlE@n9&3ewWgv6MuXB zXMnvyHy8V%R$0?tH4E|jLpvnr5)Xd)8i=1lJS+aBQ;*)w;UO?4;k8L zfyaW`V0$nRj0ER^r-A2!nc#(>Ja^$D;W;gyxze!{&XRLV$9FME8}JcF>GEC=uEu{m zxCWHxjZ>T^aeXr0yBC!9lCc(^6}K3-1}EI5!&{0z+M&41#U0JurK8hUoxj{b9{wDr zqr)aV=625Q!v&5&4Fqc7k5L06(vAJi_J0al5KB-s0kdGTC(epjw^>F(O`3iS|6lUxoYE zy-?jS|Lx%iUxxq7U=Ux=D#$6wDb4qmd2+mpFK-t5I_E+lDd7&K?^D+Aq(`r7eZffE zu1v3BJzf|K=ssI>y3I!mNAB1FkfN0N@v!2DA>|s!wo5A&Kh_$=Rn_(P>?|ZB#bpZ@ zIzYu|ua!2M3w3M=-DXFgNaQ9sbU!Syb2G7`Jh`3%bQpDsv`rYIR2+W%Zbe>RJFm^; zC3)ZA=lAEghuL!{qK^nIYl)n7W~gP|qv9`gmlsK{a?e`V5xYed^%H-6?)lvx@|H8?=2?kN7C+sq58x2lMhc25_Zp$iF){RI?@#g#Bux0M% zTZd{Ih3YzGd#9gVBw-6G z!}`|@i|ku7tgnc+>e}+kYX|5s+eQu^=kBF$pfXlstH?69VilC}XQ zk6sEO&-)@3f1!E-<-AjG{?A+Lhp5)&DsC%PkHPq>w|#l1>_fFj)APU2E~B(j|G9y> z+AGM!>6`S!elJdcTeNV6HT6ChM;)9)tgChTCeD4_aLIT4=O4}7HlY0c^WD&4xdZZla1`QxE&k z!u8j7E><|*DL6fj5-tSpl+HlX;YU{JVO zroJqAS~WMY3Y2`{e(muQ$ZyF<#tH>EIpC9h^}xqK>9-#Tr7wRHgo?GE0lR@T1EoJJ z@uY)(1sn?Q0%gu&H^}R#!sQ;`!Y}zp;Pe=Y`2l`Q{*qr;oE)VLBxO9snrd}_!kNo; zAL8^lMvrUcI^nd*M;-9}${qlGzwa1AWNt&sEpr>4K$+X<0m|Hllvn09WR67EdrNs` z&O*v5a~5t;<~(x1<3WaTYR;nwl=a@FU`OygFbupH>;$d=JA+q&G8b|U*cH4EJPG7k zsCDG)K$!!%7wiK*07ihqnaiAr+%H|cJ+{ze4!Pfkgbl;VA#)s3PhuBC+JVe*gn=^0 zA@|ArgtCi~3GT!n!T9UPwcOWDwaza%u-q9hJwdYfaFS^79IA@`Z_QNP}3B||MxinrzfhLSpeY)kIwr4++aO^ z5V=AQk;9h3DNY}y`25&{f^l@HqSHJgRBRx-tUSWTWEJHWcqG2VV+-fm89z3uXQz6y z%8I#0&WT)Ed2K;Ssi(|SI?I#mTr2Wrbq-X{*@xml9lQOKzklu$F6m3YmAOiOO+zJJ ziSM7I!;^{}b+mcX--{1jm@ItF(gVl7Ij3aG`}HR;x#qj4_Z^RnhR_(|YSV7fTF=Fe z?_8FjdS61L7QHO%_p&>Bw0X=w3twsCCI6~?Vr_MV>zym@cJlBGAAf1W#yxjro_X!Q z#h3AY`v1reM(|D3-(}4M-NwgSzSmuGa-0IcCP+M=g!cvWK!@XTbS%>$3zy-9+Yvrz zUKn-EtlQPqxEtYY4rV9NpQ~}!hKJouMu8(x1HZBc=#uM3{zv~LA|U?<2iejEzg0;EqpCh-0h5NyAfFf0-|P60&{ZsMP4Bm@)3ONl7v8nB?(j zeqvWFI&nM%h|nS9l=fqMLO}j!4SzuX$J#(vM>ZfDT|L^1ted{#Ww< ziRcM>=|k7Ik};v%T~b<{6fJ53$%A+X3#FRM{vsL8eswH~@bM{?Pn^*aHxqsckB~1lGfs zTQ_5%`eSCqkCa<5?a#HPg_JQ?aSy0aRvf|`qztdBr{=#$Tu4i~PVEncwu9C+yIG~B z!Uj2E%PPZUDqiWNT~-m+uYb+3$bk}8S6qkav3;rPjWvbbp!i?b`B&^M^oH$s_7?is z_B(qE4Yh4VTy5*UeMk9dUe=emH%aq&RTq!B-8M_a^G*|s5alK2=k3^x?5(bS*VAU^E<_)O|tG4{bwrJrmj$A+S&%$e%_)XK= zXVX4gCVkS{>QBv9{N}L(p1=8v0ssB`^0oizyT0D}4;_7;*Q8JSSG7%H(w8*pIo6e4 zs)^4v@!hqxLGgR(v6}3on)Hi5OqTCSXil#eyKVaBA9)XU{N|GPEjnhCKCH=>NNx2` zO?sxa<*#2)l=5FWEp%(E5wCZD>%O&*Kl0f%|6pH~krMvN7xBLFKX1JC>^YmaMt47J zfmzSAw)(A~#z^|Dmi9iYo#**Cj!$mhee3G}QShINU+#3twC`^pc20-0w*B1l+a??7 zfje?8#8uPotLWv;VF0MdxO(inlg^N-6j|%9jvRPb=_=t~)jl`V!4vSKL+I-Y7J}hm zF&GIlTvGaovq2dU%mrm&em0l{&I2cc^TAAzBKszT=YyP6dY>187vf(6qKoLe3|s|@ zKH}BjYVca{CJoWe4g4qg8u%3W0k{MF z415vX5AFgFfUkpMTVXedy$5SA*bjUMJQaKw#GZroDHsjD4~_vz(>D(M983kj1Sf&t zfFfIvhtiAuo;>uJ&XT5YN&R;KNlzW3Pbp(Y(Wh(&4g_V)Lf%SWbvP*XFSaHIf>9vN zPuZLp4aVR<9gGDt!FW*WTWn6`f?{KWXQ%Wp=YV26!Us+OMGtf$cqK^Lm5q$a;9C4s zK&kI6@Ln(nd=x}}@;wQPO^Ihg>_#Zt7h+q2I#ISIs0(WberbPEI6dalV==jZ{##0@ z0NW8y{MfTldcvZQ8iKzY*b(dw?gL9`084P`YtX?3#YV%HG0YXFVIu+mhd5{MK=vq- zeT+)FQ7?>SMK81Zd_pjd+0hr3c?GfC;OL3&4y&ps`spwpWmYj*Ir|bdy9EIaHwG6t{v0(>pJM)Y`@cfD6qZd3@c#k+KfwQ|rw)&e zh4UXYa3BrxtdX_@r=)wzAgpO`W+Ej?9q?}9^%+Q50Ir?_LH6B9>8 z$DHP7mM|eTIZ3W})|JNwi;uA*t^uwqZXfy0%h254=(u#YhKoy09hW9U=n7udrOTog z{|m1t$%xHWuSBx)iKjXKMJk;WU}S@iSRYW*P1+i}*wKcTK^ z%)N~Yt^e~czdWn_i(I)b;jgtGCDLJV5>!`R^;fAsHHrMMZbI-<91iLqpzAi_k9Z%*&I>~^GwflMeb<(*| z<=;lt|Buw0bBHW!9}9!{(Zm|6?Ebc)#$}!U=_*~>Td7|K$6cV(QelJTT4!FP`ZJSo zsUxXR|JqdR-U*j_aB88w9arwL>K#h@%|bsQ?oQfrJ*&9f%P>~23fDhoCgIj`nL zZ2v>V75^|*emE5T(uSNizt3(%LnI-N!8oxkq3_q{j*oZKibh2zCB^Y39bS*s(Leno z+VC~4n>N`2F!7!yUf9I{nt0p4Dt~I?Lrv?f>&k}j@5OJLcudp!dJ`XN;x|qFqlu^X zoGZLuLF7q~T)H4(&%hI>x47-cPnh2{@v0_0T+_TxUGb_%n-A?6b#Q*Ow)0ynRDFK% z&57-U=MFmgmsTy`n}3q`2e==V{$JCEZwB9bJ?_!tA+fzGw9pf9X=PV&vk1+;Tz??qHwzJv@GdU<-TMrDP@;K_-nyS zKL_GD$vy8n9h zuv2QTSHE{`Rr|7z9<;Mwy$9us#ZAElj>FdgO`(qXzx<+nuO_`f6J|5Q&@M+9J9um9aoe;dW%>-Vx(XOeeK@{@_5NFFKU z(+umw@VptmuWp>Qd49KdZblivq_1M)CromAZF!47yS!doIoo6h&LlURsi^S!n?9ZUPGf8S)(!oe%o;TF6?jt>{(8@`XLVV%qxBUFPrBmS z_oIJC)>7f?H#EHAg8>aXbo%^jYuOLm&$O)C>R}%3b@e9R(Zm7|Dh+U z6Y0OMWq)TsgUvEI#nD)Un!^(Ph8|NzpTy^$TH-CuDmik!h7kA!lic)Ykt0m}Ky7&d zlRQ#aa>wt*+n9KgKRfSX(if;LA7bJ?Ogw{$@2V}YW#Uy#{LJsgx3pd;a`!Jo-)feX z8R9*?$L5X)ro4O8Ut3=wg72&Trs{8P7{X3H!n)eu-QLV=%g;Wb=n)WKtus0tZ{W`v z_}g5Ux$7h02Y!T`2poYL_#@On-O2yCS@!h*Z<7B5^Zx<)KOp}HJ&&20aFY`>Jv zf6d2Wn+%a6LuXima{vET@h^7E{rlg%V?WAeIk{Kf`{C>pwP5YcF(|saEVWLCa{BxG zv$m#k&q^nCxtC_@8q0FZ?yPxo?6Fnnb6TnRKD9rkhX=vMG&9+KSk@Vx>?~ zc|iewy>6uf)mTu=DJD&XJoY>_qBW&}B(Ld_i%R zH@|3FN~tF&zbqfa{?0l$r|q+jk9bw@>milqF*Tlv{dpmE{Y*Ohwef@JrtfLBeNUfr z|MCv(wf!-CJH+3ZIdT_?e$9D(&n=~Ttz9kUuO&7<)E;+&2Z+;3#b20PY`+lFw)8z~ zBXG_=R))_k&u24V372Yg?w$3G9&b)oK>^G3DlMt#2UJ=SHPTY|?v|L9 z`QEAGc2R93f^g@M;zo^-=NIJ*;~y+~DD=UtTcVw(&ko_-f4Ot%!h=27lR z!YW&d4wq*x&(gnzoJbn-oU4UbJPTPXDbKd@yng3pU8FptD&h83@@|}^>YMr}Kk*k; z^RKApztQ$P@7Ar=&fizf|53I0O>})(a=rieCqpWOL!PI6f20jc->RSM#cro>s(k0F zzKhkrkzDQ^s=XZSx%lUQmz}@;NuVzDdd_@RUY|S1F2LdPku;q?H$#18JsSQr7*HsV$wH$wu3TDB)!P z|LnC|TOBpioX{`*q~3;n^Thi%Z|`zy`R1k(pPjnke(Xdk-Lg~bUoz|cso}f&f0nxZ zf>lM=S(a(7t7*-nY3;3Pj?FaZ^kun}v&-ve-+lGKU0Xlvv!uy6UvIw3tOIA#u`}sD z)>db3KYDK=t}|!%bf4Dvz@zC0{<~{j^9!c@e!9q}IW5ziO6CU7zwXwYp=F*T_zoIlWw(#n^>XKdWCa3`@MX?I!QG-lrb8@6;R2HU~{}c&4?wCSBo?>N{U^4{lkTnS#?Y zzLxzL(?N@RKrBv}d8MsEY9|Gpgz1MdLoo~%2;p5TL^q#J?Lva^<@CEa?2 zNnAM|CZ3E1Hi6O~Z}q!Q%dL9Oton7|5s&EBe?XBbzW2LM%cTduE~K8mE)h-*Ycp{Ik1Z8M(Ey%FVx(;jyt_CF^IWPIF0VQ1@PRnsxzLRvD6XwOq5rjgA z)N?cN1W@+EJ_(eyy}iIT;BZjZ2D79>?R^~$9*=(<7zP%CtPA#C1d5HtL&%JT~-_6O^Ohy+$^ z@O1E4a6H%s%m&+o9`JZD59|WY1-paifIYx-!9L&xU?jK%8~|Ph4g#+R2ZL+Cq2L|h zaPVGm1h@f=0v`e6!8gGq@E33j*pz$ofT3VMNS#?TK=%K(3c*vrEU+(_4Gsm1K&dZz zKlJ!lkBgyNY-OTUUefUR`5fH<;ggY^uks za$SAGq|W7dhyCC4QUMcgvpSVrSA><2^6z z(0cSsy6CmtKayt1luCViv1#eAQ{Rm7Qfzn9!ZrJ+UgzBdTu%dy;H7qKPKv!rXT5hU z=ksujacgj!al3Kf<3b*#9pZ-J(s6+!Py>M)s9FQ^4f^f&KcTmZbF%sltX%&u-%{yM z^&wxh;#n?hTz*bzaar+HZ&;7io?+v%@P$Q}m3a!Yg~yX)l{Gxn%9)*OO;ziE{dTs= zEGaJY>dEm!ujQHJkto^uMOmf!p0eI^1`mYl$()swU0m#y;7r+kDzmVlx5O+f&8eB- z!MDmyU<;l zfd+yy#zJgVW1(T-@%V>>Cx9csFmNO&V~r@VD;N#(3AaXpGPZ~TrJXGce1oZlKh`17 z<+s28Ie9b6yfggQ|NPqb|H?nc`)}Wne*2wy9OvDaIa)ac<=qdPrQdyhk#M~YLi_8m zoU*Rs}K zL*75ZIM4+qfb#y21?Bxu21Uk70cARl@x4!EmNZbtwCSLvHxZQgKLczFP6FG5nC(;F zfiuAl_%p#1!Lz_l;ABv~2ic&!|9t+GY?=#7d)pcK4p0k!j6?5wb z;DczX<&>1WbMwpeGQi)m25>|p^BBO%pA`~CnT!K+3XWtL5R=$DE+fv$Da^IPbHc)l ziVKRT6^Df<_r>Lh^QR0qmmi~ZajE=>8$(ds7$T1@l<-9PlNJ^ppIc*KQga+}s9Nfs zQ(Rb*U*PFolABF(#lJB**(5SGJx1*nIVy$%vS;Kd_qga3cWeSX&815K`-5SQT7F?@ zHhH2OB*_?*tk*SN4pc_Cd4JW$0ekVi%yRjL$rwrN&O-Tj!tq%Cy^dM(Ni9=mSROB2kCeHdlWUOIGoPnG1zPt9i?6j4uh-`rF~Rey~Pn$h#E88 z7Ob+g7zV3D#*f!QoZqBmUZ2~IbRX%?n#G34SqS+`ze^$>e%^gZ=sJ}K`!125GiH{x zj;48~+Rmq&=9@l65Dsx&+9G7oOaJQjQL}yLJ^Wzor!%ngiJ%+en%l1A^m~q*e0$5~ z7tXoi)sq-ByP_mKaq5EQ*DTl?dd=oXKDh46_Ze)DMUW10<6Xd=d9_wCFhL^`}QP0Fre$x z&pp804+1{v=M_Kq{@70wKbd29u5%@;;OkX^u>8~^Bfh&P z8-b?;0wlzB|EAD4U;6UEt(RQ(Rm8|0*C7m<^bkz?0|hGmntM{-qQYz1HrlPi_ut+s zzu?Xd;c-9Ye;IlGw=XjH2N6Sg@{3%9ht9mS^R||+bz zjClF;M)@6Q7rb}Xsv#3{5MCb{F5zF_O~SvY_-(~5KeF~ zPJeT`M}CWqUy<$L0@Z1c9ulu}U>=xvFoHK6}G6hb7i+bRy+fAAm zR&~DT*Q|k@LtcU7_pbqIBXuPImlx$0WfgiV=Kx$&ew_`V?;0Ln{`cesr2pxeB2ovW z|JWqi?>;SkxKIr-$w{#Z=?Te6?lF)Ti3v%g6%*lhj~btl7&|UHW=uj-oZCG-HGN#F zhtWP4$HpeOC&Z#Z7dl#h#{;OpcFFh)IY} z)G4dXN5!Q_s~_{W_mlqB`%)oZIWjVfY7Qm)A6)MKD+uJs zx=tMwz!PMZ7(2jZ5Fws@Y^JJAETOrE_ z6Lv2HyCBP3Ji}9zE`qjt-(l0Ag1eUL55 z+!OkW%zo%S%l4CJ#v$Z$lP#iOlsxm_vqMh5FaPxX>$+zzPnhz}duF}lOO$+W?SAq< z4?LZJ@;P%~*naD$_cKvtl4DJBl!-4`rpD!WU3t&)cE`Ruv2@HyVLLlbbTQ8zCGtZ} zxwmn&g#Tk=<4!X!cy+*YLC-P!Ci!QdivR2r)BbVw6VErQxMIM^opuzTR&Zk9g&!9_g-)UhAJXxK=YBrB^S0*~ zt-Uv5V`qf3RVw_A8)I(6qWv@4Xu4~kuK7+c9+>v&JnV&N8TqfSi#81^${x|VWCjP>-2bD>lH}L`{ zdE3OZ#V8cS@-1Er$*`{>*B(=qM`-p&rS51(C(^`!HTXSF zc!XZ~Wk2#La99_uH@XjW_672{uQaDSdEhdL>+DT#p&Kf?q5)gXbjC+;)F)0I$^YKD zC3PeJk2-?+|D!1XnceGH-5PNlAtL>Bz(Z-k>bgkqxWs7dUm~ zoDc8@CVM@HnAEOlaW*63%=lNeiBzE;@V`(5=sPOE2qxyB3IPY>4i5c}(0@7oWll*+ z-IEE2;}SZ<0esqyaTf}l^(?oW!pP+O)M9rj3iR%x;#`lC_kRl?Fv`{u*d@xQ9MBcY z7KmVz_NQ1jHMy|KGlz3v3Aegu=%blK=Uxq%twms8BU7LuGc|-o` z{mo^a|Hs@DqvXPpB)J2zBM}|i3LK*1pUQroVJb}>PsfrtqRh}=#fh>y5J%G7hiwPZ zQ=p0}4#aV*$4KE#Ds5$mZ3u?EO4om$N<-PjfHBcw-pVi}?HXZ&4ibhWq2o=jycVfd z!nAE7sS{lzI!wwc_vGBSqc1UrG5GVBi~M)(h84U1d)37+Uw_>5FRY6nMy0e^CgFE} z9sJX}qK*-tJ{9w~i$*@cIR1~u6PWm$+U}|Id+`J&KENd3oAgpla=b}iudVzYt=dD} zq_m$NZ@%x`@AmK7e(4wMZbz0<;rC3wY3`uK*Jfm$^4c>$>a%@4dTp9M2#%w!+0%UG%$;L;7bzXdj87=mp(G}n41}8f6uK zQqgfYJb%thZ+5xxmBbl0e)xc8y{y9DZaAX#fEyc@ymU)eXn5So{~(PkC7qv6Kc@NK znNizsOLJeGcH><^tp8Bqk1cL^X6{?JJRkmZ+jnnjd)^7=J*Z54?FA~Gnmm?Cug0Wj zV&c_Iyzho6xv!dbR645gntDyOP*|K(<;#U;keYMD&L$jn0s$^jLibft_FPyx#A&FTc3A8|OSDvjsYr~n1{zp}ji zk}8@uPTe~EUV#6zwUjcC;zFRmDF3JW%io3n`>nb@&ibG2!Fq%uGJqT{aX-LAy*^kt zJD(r7x1i#;#1mfc0P$RwS7<%_(V@o>uCHrx1nYwus_T!juNS^6$>tm9*?eOs(v#wy zfNKh0_OU9HKi@c|49mP(rD3_A0*}~Q=0};gw46=mOIf&XDx*#(Se5xW(*9bddu)v| z%h*aEVLrqp;@2#*=uCas0QqQ{$gnlJ7n6+KF-qdslx7jDGF4Vt(+6K7Ie?#{%C znK(TY2V&w#P25OrIS>=qXX5Bg9F9q6$Hax2I2IF^V$%IF=_r|W-;Va0HIr^yZ8^!h z(q%Jom?kdQ#MzoSXVV;nX)Ty(Zo7tsrG7~3OTP{>MvxvfL-T4Kk~;j)Cs5?w6+^<0PIuS_~uZTFzNg$o>k8VJ;Qz2dgw>!V7WK)BJh3!n8z4%ElOSci zL+lC>Lzy88ECCGgf9b`==$ch0L%k%0~;~wqiBo|fing@G6lArT@ zIl)I9T zJ$SkOpUszc88N-2o((d&)s`|QskCdnGguuf&4M)^PBddV^|h7H<_wiqR~5e{X)7I9 z)#kL0>qK?FN5wl-{XIF-=OAgLD@w}xeQ?^}Vrg_7_N^+E=deiSTjMz_sQ5;3jpB z?c-~dyRywxa`@HD?bK&$*1^fq4JUOf^AEB~;DZM*w|{jS>r-Fbl=HexY*A^+cXvdn zf17c1psTl$%JLt)%{$-H>TN{kCAPy$nRu@+uax- zJig}=F9N6gH@%mQ#H&YGSDYL-6Hjm*D4&p9?CUc4t@|I{r^$8ljY`DHaXazkdw&Ng zugYB@({k25pu98pf<3|e!GYidp!A7M&!}>Z;kW+Q>%K$MN4;J3n}D^Ec#{6ZpuB&Z z!PelTAg`gd1(Y$+W1!sU6kL*epV*g%-;$mT5z=vTTuMAie+fueW?cpz3oZkX2d@OB z+$%u&R;>cV!D~V3FRlY6pB^~Z6W zCe=M5I&nM%sL-L~6!RIMkei#GRaE2&=>Nq8_&;S%>@R3H?61iGc~yUTl*qrst^fV4 z`hO0mw#4StWQ;FjyNuDNFsOfJh{zTT-7$0Kq|1HAIs78$W#9XH3_M&`NkwpS_H<8< zS95~F#A!pE$)rOZb$tRW3kX(nu<(!Hsr1`2{*Mi9X2+jEd`9o+6ILXv&hNF?@rKE1 z`;a{BLvdKL2fTzyxoVcGl3$cE`IkucfS2?o@2WYAjM6Mr!o3XcgRF`&rF#lX3bMSy zvkeJtJ5p*K*+vW|j_|y8hHF zR-QlWgX>>g>`CRhB2*o0EwV}9$E3ew(#J9BE7exN%)}3P)P0@P=!uMH!^VBm>yt(Y zzFL3P$+fp(w;@XE;pnYp9I4W;si%3pDu0g~@7r|ZDKF&>+i>=+MV>YDX`3p3%{7H4 zJxvo|WYXU>>ED_3I!$_cCVfwn?KzXaq-jmLiH};+PoCHM4GnMjU_gTooj(8CTK2>C zGtK&>CcVG9(&IDftJaoZs;wTYiH|brv6}P*Us3IFYvaMW4?O+o!!1Wx-#0(C^NnVk z@xreN@1*-1%{A@9FW++MljPuW_{2XG6#l0a6y8SoF5#QtPJF#V;Z=kO65eJEcs;lt z{I$GF?q0o~^e*_79uPHRM|}=qOK_rhC%Sg&kW8X)w~jEed$s|Tb)#bM>?H{UpT?RQ$$}5bE2iE^(`n8Y4+W*r1<)2jkkF@9N+uHI!;<(b2 zU^uMy#Jw?Hdybf4IzTi%kE3x~7SmgO~X_=a5T$BSb!q zQnGpzYiQ^$+vb++wfnfbPHb)sQZ~5$RpDpzU5;aj^JryQq=d}6V|B%y9c|9Y zq_bk;>`WYliF>LomuKRDOkAFcLo{)MCOcXtj?c6xNFQ1TN`BIT z>3#-XGJZ>b^}wz;IpT;X7!OLnG#cCq=Dq#vd5gV0G;iT>7LMJkAK@(Kg`pdQbL?I% zCZF4I!ex9qtkRCVa2bcQf3=nCtl@{Y-M*JN-%Gr}5vYMc4b*uJFx0Fo{U6y!xQt0W zMFAe|^?#+_oTIh@U|<6PG;h$qNsNn5ayqZbN$$FJ2pNg+2Qp1infYMQPRMsnOmKaov_u900EdZ!5yEP5XW|flZK~yyzG@N zHJITZm0G6?K>D4jvB>SvLFj-fC&@v)Xx{f8+S%=H0ih z?oXX1z@`6@_JOReF3z8YU%f-s|G(}W8s9Vdl)GQa39a9?ZzQCVX$@O#c~=v^T3f!f zuJ|+)?`q=lOt#}px{UYoeO>$xdmrL9;CA9Z#Qj?RoYoL=)j2NVwW`~|5?!40W2@@o znDlTQ9USXjxH{Y){Sf)Tjpb5PTc^dPCdDQ8i|n1tq!q`>R-4d9pzw`yNcY-!&ba)X z(&Dn>sot<2sXfEkVEr^X_eV)X$`UvNH4vzQBddW!z5l(j;pPAS>zR(?SuU$~-+(|m zhyF$e>L*Y?`fZh&#K8OIj6eSD??q=TNR6wMQ39Uq>*ol!(2xliZ^8JY+4)7en!hlO zo&N0iAGoi;`|K}I1ln_;p9}PJmQ`KO4!jqE_ag9K1m25)T&;P>!1pllJq&yg1K-2I z_wd(!5B0kf_#3E!!`FcD|Hs(#eQIl!l#bS+(thTeyaYS~;_Gt(c*iFPE6pkli_b6cl!f(}Gk9Rn%*r{4s>$|^=pB(c zAtp0BzbLbS`{^xdl;mdDZOJlI*)lMz%u}u0y(J?#+FJudU9ut)J*WZmm7ytU5HDCZQ*kCrF!SfnXVYRkTm7_NAX|ca4se_y=z8Hbk%dM{m+fB zdakYixihMs>)>}T!A_IvQ2B-VpNpw_U4;L+YH9ZOJC|ao>D&bhum-SY(ce%c|eNx`RHLY|Qm!spL z&q(;zPHIur7CBFNb{UJYB(3_A77cg7vFf@}y-PiOwdCr+5vYMbXAL-glJrq(VfzA5 zKB#_282ypcpGf~A{fsj7cb;D)en#=%dB5a+llKl)TFZJ0=XXTOduYEq@-C@Gjcvd; z{UY%*O13Zw9Dy1L)WA`zfqEUZ4ShR<;Pv?F_M9X5GIS*6)wGY`&shVkCbe}y@E4u6 z-4EydW8Jl$pyQ82max_GB`CP$6un2dbN*cX{^uhxpf6(`=lqCjepwLxPy1vLID+wk z>^W{9!69jub++wch+-{Z9O$3^n#syuzKS8&ugO++{*~Xw-$!$+eEx#(nrd0{iL#I2 z(^vrRUq8#H>(8N_uV>Y(7dAt!#a7YzjE0_vUv00WLt0;hzn%K6|LpKPAA}rMUQo5X zI|{4T|1bFc@26y@WvwJBDZ6~OWp^O|^9`ts^L18M5aqiVe;3;?@DhHhC+D~u*`lfA z;dw1sRMkI`#Qe`cd4bjnvo8s5xVY;1{+H@CA

{{OxUzl=l+b@08y@6@dRy4PZv+ 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%0DKb0eOAKXE7S%D+N`##hX4aPRy`|_+0bUSY~>e> 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 F{09I5Qh@*f literal 0 HcmV?d00001 diff --git a/bin/2.0/localizebugfix_mm_i386.so b/bin/2.0/localizebugfix_mm_i386.so new file mode 100644 index 0000000000000000000000000000000000000000..8dec3f837a292ded6181a981cd857a102951f092 GIT binary patch literal 19172 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 literal 0 HcmV?d00001 diff --git a/bin/2.3/localizebugfix.dll b/bin/2.3/localizebugfix.dll new file mode 100644 index 0000000000000000000000000000000000000000..ad4472df0321b8bad8dc61f1c610765886091fc2 GIT binary patch literal 51712 zcmeFae_&L_xj%e1*(3{W*aZ`e6?7$05fp(CB`m>&WRsu-Hf-3C@?%+(4V#!`i4)v`@F}t(!``RSlMUzi*@8U27?K*VXxW%l#gUU#PQG)midZI4rfk3eW7s z#PMk=>JxuD_Ucb}zw)`}esb>4&mUv)S3mz9{K2oT{d^bmr+@x1^QU}%lKI!Le1l)z z`uRVx_)W}TSyk>OTz`pjyN%

EgI8KNL%}JpEkEO%rtEIc_x|bqe&!8{wPb>RH^( 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 literal 0 HcmV?d00001 diff --git a/bin/2.3/localizebugfix.pdb b/bin/2.3/localizebugfix.pdb new file mode 100644 index 0000000000000000000000000000000000000000..3f0d8125a8465034d9575a1c178e8dfc58f0285f GIT binary patch literal 846848 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

53c#-CN#W#G{MsutYixWyKqXbDpOE3-?%ed@%RI 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%0A6il+06KHU&xCzt%>`9LG&`7RewieBZ-=| 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

hINvMBf#BG+=xFm?a}uHSXa#Z9RaQ%r*(v1 zfjD;(E*D(sg2(eB{H_R&L9aGZgx?*(C*fbkpVtw7PXr&Xm|elI0{-O)E`v(aCH&q9 z-iway^Ya?O?~C9%S!la4jr${<4l%|38gLH~*L$E)oj}3ax3o>K0`5V>q0KQ^pnUNC z5@%5WkK1 z$twn`l_lS?v<_uWBTiCJ*8L5L*FhZW4>i0xHV@`nCeCl2#Ek=nDN%4^@!ha@0KbKJ zpgnkOUP+}d5Wkgp$qi!j=4`;btC6?QwY1Sqh`XKmaE)OGH9qTW2l2?a%pBvjs;v=! z3fxZO&|ju;7(BANAo+PW;JXO##=*FlYHWa(Bc8B8LzJZUL#zL5d65g7qBCQ^;WT7!ThHh&sBc|+?B)) zR|>pO$2J?$zVNre9V3q8jkutlt|A;0E$mCBdoaKEgZ^qs2fn!qRf!VXLU8@LhIrKd zesqsMSSvCf=eKJm9t=S9Ho>8zm*l3Ww9U6ca~)|0aNF4TodXpJRF)_9>+6X}eR%Xp z!bapDfWJY~preH10HhI5re%5%_#26zs4tI;)rklfk~aI&O~k?5(oC_6LCmQDa+k*a z9`H94k8%yc5aYt)QSBVQ{vQJV7UC5NZy4h5jb;A%F%;dw z{4wx%6W>!WmFGla;?xq=(>=rut@hC|0O}e2gI4Yy|L=(VW#YMxkw2GtAXyJT1@7KN zx(CNbkt}il3EX|c7nO_t!PyEmA-G=vcfZA3Ji1z%U5zSk$XrWmem(+T{~iSMII2?ZM9y)7S?IM`n)ZW=EYDOTfd1->=H zch5mc=as-{yGoZt5lf1px=`Uo8SXy%3WqC8sR>0Ssvdt*9eEuHRHK({ZE z7p&on@fdv(@Hyfq)zlU#S|92Gt}n!mmu4@YM0cioMC+4t#Gvx$v>)#0x&99;4)?UG zl_LkSL1%Bk^#hGBYcFYrR(r7wK==@MV7{*){*=Za<_!wor}3jLaev_o&|O42TMnim zreI|fn@Nb~d~Z?u7w9fkeq3u-*P!c1xi2G~uHGRTCrF#I$&<8mq{S9wRjzidMeW;- z`;SGRR}8x*S`l!`cR%=+N%xX^v3k_EZ7;fFxE@>pnw7O^cKiE?Z^KBx5Onsb!5)nQ z_dG;0y+08Iq20n9kh~KF-vzwM5Xf!RfwsEUD=>Kql=&qLe!Z>;^GBT&?lJodBba-r zZv$C&B*;&PvniNGr|LTyroN4L2${wVKQN#sVbV?lcG zvlG1@)aYaB&6o{Bj{KL`Zat>P=@Wi4XHj>#q=-mx0-$j3^Uv1 ztXu!hI^~^E3^G6ywZ%{YGs ziX@=V#haEHj8V|?`(k{5LhG7+gs-Hu>>E>vw*@{w3iE)gejtaqMycy8=Hpz6m#XpvKX~!kdnV(9| zcX*RAQvuB0d3+JZ9ou)4J3YIi>9KuaS(xhQl6U^lOR~&Y{J|JaI@gk+ngn4aB7Kg< zD)_T)ct1PE|0nM&OMgC1XlDCL=*;Y&tBBX`stbBVBt96>4%wRKoB4tNoppUUU7%x; zb2xet=3zf3c!mM1w5B`n@aGrZd1oGYw%m?8ue>H@bNrzo{SJ)h@C=35SHm!BLF!-y zd{_rL)IoS>9o;e!?m{^IULgFEh^HCOb@6ZVXMcMY^29OoMJ?|U$>Zu3lv`vW)A{;p zB$x~Qv2d>Gb6zWBvJqi}Zn+P_1+-}X-Bi{E@&=uHeb&$De$79MbVkrd_1TfW=jRs- ztBbyVN&7OlB0EUTPST!NfcE7=n~$8Vknfd%A9E|CXbhoa7&>I^G7dS`1@B$|Dq!}x zI`V+qTo*}y*mmv&1!Z8i|0rPSWu{4*7g ztjgVEjHB#pgZdC(j14|px2Z2Iwk2kEuZ-3{&;>}Vt48-C7~bF(65)+*CK2A`3W;!= zt44PU82<@wArU^#%_PFdyFwJsfxaE96wAin9nSAz`5V3%q1cG;5E8aUV3oS*3klom z7I6_IUgHSsa`Q(7qUGed<#zNdYUP*~!#muHDQn>?Vgu!b?CXNMgg-_(Xv)(I6U1m< zO=2%ggXS>y(%(9nt;0v!Qt1j&EK2kw05OqAj@w^H+8nohUyph8?S*?dm`ALya%`i$ zbo~21L%M6+3{GX1SIbl|sN6;PwT`i?6gs0eBmBA;9<>E!1Dum^uP=4P@D1>t=9PMW zjK3b~->Bo0ATP!?Bw8~;P-$CRPc*9m!OK-$y4Il!O3EbMP@*1Yle z?*_jwAy4F)?+CbPy=Qf#zazl-Z_)T>FVDTiHnafe$?JgoJ^cMX{!DITzTbrKCP;_Z zaB>SEqf1U7yhJC$vd>{&kWEeSo3Kv@o6Op|t) zsIy3?OT72*k-X~;pDpsfJmZk2!zJ%8!xu{AAA)l(-&uHnkjE`9a82r({gm3f5MJJj z_X7;WhHL-_7cc_wdxUL(!S~DzHxbBq)UJf1{-9dBJc9YQUO6O-ftHzjj1IKRYQcLL zw)}oDkzaJYXmgX?>adN|?=`Wr4iAmfC9@wR8t`qvdE`S#gLCeh@og!R_!jW-xjwpR zo(80!v>3SvD7-kpfT*lz+K zzc<2sgzruun+VI}4uNi~gz@1Lo`9pV_R) zp^eEmp5Mx05A^Zgr1^NP_f|gU^QUX3k9&u~{CX(u^$8DaSk-)<(%x+OOQDCgvXOpVcrQ zda-)^oWi`vUtbrWSJaP(JU940t`EBS_R_rlufNsv4XJxQR@657 zL*y5_`sn=`&if+}{r?8E_K|%~FwdvW`|IsLnQo|m;kuMX8h;z4p?loMRGQW$`c1Vt zm8Wm^yH)j?ejnAWgT>iKq@U|T!A@wNS0rhvLP?L2!jQO!$KO>!Ia_Y>*Qk}$@) z$U3QV=z9H?^HJDeO<(w(AV11Gu`e1(m2LA=<9R+T-h+3*;oRT9>xc?V1EcmZS5by~ z5NUD0`d01lJim2r?ROhl*PX$;M>a1r%Uiq;`N*=QqH{5ETRjf0I>qP&DBlOUes`^5 ztAIWydS5eovb2Vg#~pIs75kf~%*A(?XeMHGgq=mX4OYeMCk*4wfT5+8GIeMPy4{)< zoy!~T9>BWc0&rQ(XnlUk<6L)`@%@pR&iRDzUE}S_^HScf~p*x7r$$%0pGSf2XRfhgtQZnwa-C%66Z~`-XFT=iFNc4 z@&i4MoUPaa4B_n8yBwUD!4S17CpEtA2;bw%Vi~3gnR5u=>u?fEVyNjnSafrun?8g&7jpMDUeCv!-O4(SrV24tJZdh6NPw&}jWKYdkAmSQOwR9q6h50$?Lw8^^>sXiwP&e(iWk zy)ftF@+@bA>)7}s(C|&NhNn#uVPp)tl5ovfKVPh$EG$PKmh`0{O=nDADrgsoQ25xW};bHq!hD{x-oP;Xkz;w1wh%mz|gW7x^5E`TPRm_4xcU;6wh#CxgLu z2Kd;yTNYtETeE!d+^xkA$`oAlxmzn}dG59W-|WBS!!*cu6JQZv35xmE@^y zX!0m!0oat_DXxV&mFk?g2*Z0*vdmO5t*h1@Zk+8wKa}i)*3JxXMm)CjaX~*J-1^BAfe-u1 zNeHLKKUvea{+&bl?5~-=#ql8*ewuM{zuHDyP0)0JmfxNFeTsfR8Q&}y^JwK_-ud?w zz>d#koaKw@Byn*%ViU-`DBq{yoAi_kB3`JGwRw4eV<1nINAiGpR=4DtOYn^IAUL!w z(~~v<-D&vE4{`Ln66Ynxow3e)mAm`w#me3C-h}W$*&;p|tCq$9Srzwo}X>p&caZe3kXQaTMr?6*$uD7ysbgI%VPbM>s zF2K~-UeY`*;MFzH3#46V`1u0+#t;X0+pD#RLgKQGN9nVfhWwi5cEEVu8}%kMae9F0 zULYqe(yTKeyvE41hjQ&uZ+t0@h^YV-p+RFP_@i2LEOkr82+mC0k`i3UtJs#Y$ zkhp!r!+1t+czC>fYLM+s9<3n`Ct4x@4T_uS?;dW9yA6Iyt=uK^KNm zhOn=(jrtLX_UCcm!Ru>Umi=0mPeyGvK02HqMU6*gL3n6%D35o_`ltH)kRO&Ah4GNP8~oiSI?So`$5J^3$V4=FuA_$3`8iDhWbu#XfdyoUy(xz+YHj z7qXtv_QU)}+lO^b*)=WBsKy!7IAPyky7}4T1Mp ztC0?m@OFjw75N0qO40Ot#B~tYOB4F)Bvdb=!+9Ryoe4Ph^Lj^MH*i}LIH>TT=`kJ8 z^MT(gcsQBoW$S+L(S>sMUf{Zj!@WQn%;EwsL}#zp`4!-{Cvl=wV!ZQ#+o8B|Sz*Tu zcpAN0ooQYt zL9>rEL#uLi1TP3cZ;d+Sr8=dV22GAM6i6nxC0VWErljPn09+q&sE5Hy<#Ksg7D2K@u+fX5|04&^Zlm8jaD!FsL6StP0o`za-?B`zv8h)0uc)il5k2Q>s zso|lX_&h-aD5^C6XoWG3wEltzsfn4XQ*x8b+t>v-hC z`0`ArQI~cMv>dBgD%iWZyhZQUb3FbU@TmR}FLxV%9dM4_AfB8KG0txQ$1xn>#^(3a zGRTkdYk=SC@fc0;R)e!b#(N{+U2#0Ib0_>-z_)vNUu71)QI_fd!~5{Me0Def{ zDJSeYz;*&guMM)$>zwlzz;^+zcPytY1Dt1W0M5p^%`tBWESzIbL~WnIIfl~=cyi7- z5%bI+fsUUW@vV0HO>+kC39^6k5B0OQ?PiM3k8%GPycrjD@yM%@E?~h>AFh75y`MC`FNw=5vk9|+e7ozE0@~4RB=aP*0#CC&S<_GQpoKk54DgFRR7*Svlkr`G|8d?#QDSpnY8_L~m6Q z4*7)eGVfsJXIDg?dnb6d6OI!>J|{`p? z__r&5sj}RJzZrSF!{eo#oJ;R?vpoMhJ0|vNalX7uahAV#BmUiPMIspN6wI&iGdEl2 z3uu}T!r)^LqdA7%g1Gl0ZQsf$IOYY~JDdzJEbjr%KKHrwjtMRKns2V!o1)Y);a0c2 zacX(tIsjd~0^@qbok*+PsP5a{;Rwhv*org4_XT-_9aCx^{@)mb>GBGVKE}mF+kV;D zct7&VahJXy6=M;;=RQ52-#;-1RgJeF2|@7~{-E+Q*@Jt2{@LD>clkd=8mvtpR@ybr zJ@GXB(1C6~Fb_S+=v4njFk8iCJbZxM-L25 zAn^m|G&T|ryr+_bx_*9cjkw6(aXRO0la8t;qdLYvfP6rYMXO8cOSd811}V2#Sgx;# z;~x+I2;l7rI2;qr7R$ZZ?$QmD^;wp;!%Y-si+zzV&W|E)r|X8}GWZ|F`iOl!4H;w{ z-vQhfu7*@-d#rJkGx(1K-&j;ji@2?N27dyCfi7pcfd>k_`)Y5zvfSI9c-4920*sC0 zF>XJBxc1rM)~LG%OQpC$e48iFd6VZ|{?1i=@67C|?hMk^^DeuzAon)X$AF&#L=Ea~ zmEeY?@i}ClC-&=4A`QQeWjkn(&EMWuQAS#L*h&hr>%A~UB-P*^I>$M+#U1FxOj_ES)Z8I2O0>w-J`Kf_!j) z@j#f51TM~p?JxcTwA^2O2jABBm(M!Q^-z&GX56;(|v@9_=J5Cur9>M-a{rL!oCdH zb`P^Xj->Tfz`1V#t+(caY(n~b0q5Sq;G@_QSw6l2+%Dk8>&ZBT?+M^xocn;=8}d_| zHKz4-Tfn0} zk9)Q%50LLxm#-~BO^fb;b7Aj?;YUGPyIj6hA(v_Yjgmg{EzLLgDh_v_^K;O=s!V+v zAn-?3!^R-;lS0@=!eF{ceHzQmDVq1D^UKu5dbxwJ;|Sw6UHK7)yTP^mLJVWN@R3u? zSDCQq$2RLEOs)}o7>lumFvuF_w~DYX!h$!j3EM#!q!!X`Lp|WFne4+sJ;0t68-CbG z;(yjb`r4g8I5Z0Hwgd2QkcT;TH*V=RfqY+KKYSGY*$>|uo%7+0ZvSvkzW<`${&5jT zaX8sG%=1QnPTPd<8yg*)%6qE(08$)&e6(_&n|15+!x5kZa*&f zbq|l>jI@6+f1rDKx_=UNzh)(Kjr>u zXn&cM<35S}g?w#1|E!sB>fJ@7KcSgE^}g!&bR2Pfz_J(HTR#pMM%!?%tyFs;aEqV( zA@LW*vGW?qXD@`_(ku-7)Jw4M^X~!rd^ zge41oOnI3-wnZimGJE82k9pggo;MoQ%KSr`Qym_bs1^^7P4u}5j3=G}|2(J{%qtU9 zIFz0kni|5b0UDl4hwtm}nck04vo2Tz3_*Gsu;9WY7CDY$hj$_{K@0Up1WG%+~ z1;U%)=|UEI(1r0R|2$T_ECmF7IF5N|Z@sizL7SHL2IXPCPMBx%V%nm2#&>$$jc!wr z{*0z?aw+4}2ON2jUvt{6?l_HaaV%}Cx3oCz8mAf8eEt;IaV*zaTFjr-ad_qw$7yvP zQTe=npZQ8l_avn=*_CwZv{}~~^XzyB>c(W(QvhfCS^gOR$$;5kbGooWi+Rc0jy(5h zrpvgeDxKxe`c*S+)@^N|m9s$9RT}N7arzysH!DjQ;AfyLwjVeRVaDebN@NF8u z85g&g$>GlgE#>g-_-216AEv>$rvn!8MJ|l*dsF1_3}`8bdso70kgT#|3vg%>HwITB ziV+!eBjETK#qrl-z5Lk*1m$rb$73j$9uGKWa&MdGW%m;R>jI3P$JMXLR0V4j=}!c1 zyU;J;Arnu(88FJ_6R;=1#Q~vvB4Cusd4L!C1|g4=f!hU~O1X;m@gTH{Ts~2xm}MxR z_EUhPTn>lCmMzF2tFkwE8gP`$#aS_2%9`B$bii{SPDjZ_+ysem&j7BEI7%z1Tguwc z0xa^dA@$voc{X5;vi3=_tS#pPCqvfW0Xlx3gKx;%Yx?OBA5fT!*FM`@`>qiC)K2i{ z807CWqu+k)pM|iE0jBd@gsE?M9=`cW!`XQr`K_X3k++RO%8$EKd1l=?%9HWxDe<1a zM!a)1p3Nc1rp&)gi+69E^VsV4YMd}%-0L^fX5D!ywBZ?JTrXL-PialB!F7Q7pq{Fk zH*8OoKK;xCf?e$FM~uMZU@lsVbKt=`w)em}zq1Y~3v>fVoyu34kJLPDay^;{TZgUw zWF15temCcRgX>F)_bt$po_{CB=?Bg#%IK8g3ZX)90#}~&N)8ZNtmm}k* z8t6EV(&!E}&~eV&#d+=x#^&wfsI3Dp0?l?$W2op(DD(JY z;8nLY)Q6XMsGy<^8*#nBaV;BKK2+g(A7TA~?ehFm&$#ykzen-qvg{+IY(s#nZb|bh zDjnf@A#hy7;A0r>wUCLCBH#Itcq72&fJ;6t;PWyDT%S*Cq_X1I!%4uXPeNO8vr;J0 zzdx&nr`#$>OoL_^GBu0?gyWYHFO5F{LJE8&*g@Z#_ulGu{Yzwv6zv&F-(VlEJrha zi(6hZovaJwT#>WGeOz1*8TZP#9y$oOxn&jbaBis~%sgOmfoxUf9lFZ&_T za&9?{Z_X{`V{^+5eZ4 ztWlmV1J(sP-u5+_bqO%e2cgVb0gQ71RRMhN0TwGVE(z!Or+H|E(J{0F+%DiuhGf2~ zfb9V+VG{?KI(ox+hAkYz;h3PE%8526z?)}HCty6h3UvHjiEoi9Q+&p~5wy*=C2O4B zHJ_O_LROoMOjgg&HJ&xDbF3Qq7-t`bMUUu1Xmjyulp)CnNujLN(+~&!sN=bBi`%mC zHB#QkU55X=b6>aNB<9Wcd;OiEJ)-}8YW7jsF?ikAYb9TN3X4-l4(E*DMA+sG()|YhIA^>8-~2S=n&*t)0xjo^Yw-QgkTcjnauPe%O*7nz zcNVZr3(#ob=Stp2hBMJheb(#PYM^a*FkBJMz3*>?Q7?|0?yD;mf96h}@RtEq;v$}; zLuBongl}=PmCB0O4KlnHJ_ibLPGL6kgh5v>uT1fZNWb1N0~;Y#?N!co%YVt!d}*oF17lEA~0s_IYa%d{5pjO+J^ z!f@mP?L}OlS4Qx|*rj_PP;8@P3STVM7WmwfrA^#biVN$T@T=X@>O!9S+4#*W!mn|& zbKUj1QiVEVJx3w@TJ()0-eO;5O4c*s*AWiUEqr5*_g&zx8)_HGQ+(J-+l6~L`0bv= zBShlcfjn4$H@ZW`S==t3Tf(y|`d%aDq~Gp@eKs6H6v{g4&=wq^WEk0 zq;xo|Ka5W-i&ea5%T5}PJB-nx8qWrQ@r_yHz7rb zoXIX>xeMGAb_2hU(VtG5ubSk$N@?#bk;mJWN0{Cp0T!lrqo(%`rDeR&AWuv?jQ7V4 z@ov(1f1>ehPr&k!wkCCDchXwipDO*$O3(VkY?B39@M);7HR_Lfe7Ev3oeb0DT)}za z&+)qku5mdxxLZh%c<+U2C>hrIZ*6NeAah@{nua)jDr6X;7)g@Gs`w>ORYOi2pf_pI%XH^4_EItu1)hvW6Uf z0q{7z7WYNcA-yjtz3CI5g?1o4^T|K{<{!(#`25Ws@mD&1{IBx+SgemEo`2+H@i~|B zFHV1xyI13XUE`>1$9-FK zo|fUKey++a*)QMLnT`h$&+_wK3^j3Z&ts(d}C1Vq58{}SU&ywbRPJ?9sqAWt`zJ|#GQc2 z9n>k`Cr?~KGYcXMR?{rE;c3F=JlRKyImNk2M{Ql)T0hjxxw&ZB~?*d%z znNk8%*q;F=_e-&U!#W^JkNMgzdBxkyGpjw7BVGo0FX-i7DS3!vngOo2kxWRu+$|-Z z&TJITwfOzO$=y=o_KRRgl|Ymx@p8vh^AeIUKI>KPnF5bji30|{es4p3xnrs~ODpho zHmkA=%OiJ7Jq{8Ot{Vv2$0fdx<@NXr;c!i44Z;UwI85Y*@Kk5~PA>7oFlOjrTKl}F9Ux)@zeArt?ygQuE^Kr*MPr)cqqE3Dg*U$c|6*W zeFL}~iSvqX?yz9=7WbK(h_km?_3dEWYkw1QZzdjXbWm0uNmT0KAAq|>_%7j@*Vw<^ zKLUQM!m*{0aq)e?ZWEYq9w-9K(8n{AMVs$_2%6h9twEHahdX@TH?uF@A@Rio)Lddl z?*LnV{||WFNxC7tfxN7WBzjfUF~Ik0?;;*Ms|s9H;o|=ic1^2t9RM_3Z+An8dl-D| zbGK{oQIH7wbugaiWBLA3@CfA`lQ~SrjMuzY_hZsx?fEy2W44*>n;0eY%VY9VJ9f_D zirFgs#W^EBLh$hj(@B<+)zm>caakethnSEYeO~{7|j5>%SvT zM*_ZE?#pm5^b_Fh)9IR=HLU5s;k~-ArL2rM>gHk95Ul}z&nAi_NuS|1>@nqG4J`*@ z?R@J{^UiRGE8uNpxM9#SMp&n-SIuuY!+1-yvVbFGqv^+a!&blwbMgE0gmt;PI4Te* z_^}_*X6$D{dAH;3zsK@DWN+UxZRf;fR?5UZORLk%bDH06pnwgkygNhNSL`3M{~4r* z`*x)nDi7t$_cQj9kD%Syuhz3s{4el9pP)^L)HBPI1^-_J{MAPBG2Tz`y27i_$Dmz- zWo+_J56^MXSJY(YQL#&9It~(>edIk$jrMrnN!gCHRQDohF3&{R^eDt-!J9gk7EPlW z*PvrTMp{A3{TU@m*5UJ*#xefRbdaaXi*3YT<}Dx?z1yJ<|)ccfD@Y~ zgpWfUrguEPN&oyc=!qkrh!^~^JwwJk^OhCd8OJ=2&6*!6e@dDsYMMM3U|g1kac$pr z62eSx7vjd{g3mU<`ANfB9b36NLCbQ%ftS!H^Mt&kEc}G!lKNx00$d$5X?d`8o}%e& z(R6lc9r?CM@=Dfij5A(OQ(jx~JtOzivX1SCx3%))FnXt6iZ8^KpedsS!MTF4cG6QF zi7+aZEFWnUA<92XxO>zi}b# zOog$oEHCsWM}AKYVDwE#*wX{pOJBzGxE9BDwYd90*9bd51-4Jq4db2<*eFKZQ{9Q# zQ^C_dt*+O*%-hFn0bN|1;fe12^UjMZ{eb<-y?DFQ=Ei&IlyALx?!%aW(&o9YAZ?xJ zl3vXl-lO4oc{BP%IPWCvSAg3Fp0xXVrt-G^VI76shQEaUPDJ10o~87r$D%C`ZG$Xc z!Y(R`x4}JI)@k_b#$29i*A($+bI(y8oab0Ro9CVjcsMugM3`fi zW1Dm=E9clVHGVTLo)2Z5W#DTZwA5oi58qawHg}y3Si~2(Furfsb7{UMZRgV4K^xe- z$R5b-#d#KdI`AY{n;5ZWAbbblT;2e0vNt&cIG$^py$Q#`F2IJc9axcrDQ{P?8!#IO z^ru372z{uW12{idLRP?;aTIGh`iYK;dEx?DVUA@zwf(=w+2mu~`D7hFAL$-<%-82L zk+!W(Y$t|a0Q~XUtoxj<8P-lQuA!X}Z!h97{tL+){eraCFMfqEtba_Kzr#NAB817G z^!(e0F#U&~k8gg`aIXsTl>!L~XNY4{0bxA=AA{PbeLtgXy< zW(YH1oVkF`=Isz>{xrKm7y8cZK{)h($vr8{(D)t({fi#wHXhdtdi%7+xmAyr-oNN6 ziSwQMGSq2u*NA#e44rI$zyp4z?Hz-B-c1Jq-`ChTo9_wbaZHI9p!pK>bo?7J;I9ID zS&>V#?hR-c(+d)|3mFghFhj`4iIA{X0N;i`j2-cJVPQmB>kiV;NcaAJ?*?$Nzq=29 z0H^a!Fy@DT4P4XtfYRcA4{pQbW<~>#1~~a#pmoZ8!fFH$78JO*mVM_4Qh;YeYybzL zT*671%HE@ZZ-M1Dl?{b*jN`p3jE(FV@b>ws(>#shs*{vxGAdFGLQcS&^BMaI<$b(> z3h6;D&oGx5yw!2@IV)REQdpjt|F!^!TQoH)q!^F5c39TXf<_Ljv>b$Yh^34#FTD&i8ar4#C$l9CS{Mh&KY1b1hU(%DZkG z@(NlW-aB!(2Hc}MOM*Qg_O(gmiFrMSzBS+C>yhgmJU^KV{V0#$Sk1ZK#p3Mcll3L9 z4`KQHT$Hr*H^K%S{7XQ6$z$_k6=&h4*+_T6JPj&;=)h>o2DL5Jfafp=(^ssuA;&APahuMKbqLFG&6oCF)$6hT zTHO@xoFHFC)Zmi$H$*t@5pwhtt5cQ9qf0XtJZUlmMPAg`+hd-BwsJB(%!x9V8)kTk zOZ-V_`(%T9-38~ygF#*39&^*$71e{dy7emp>wt3@dHcL4!;niKSytaDq=5x3TpDp! zi^pCTu-Tb%WRF9-R>IVFiQ$b5SIe{3zX)p+nnHDP&fEA9b{t?!^mKxSCZugAyl|um zej?zw;S<$Q2g5k&Au3Q zy%n%3EW@q;Y$r`|DY9>2TBj=v=OIFO3F7VW@pfCDxIfwl7}8uW9`^DH#MJCdgZ9i> zd-jb@Hi{N82(5{7o|TX*4wS03dZBE~c`&~HdgA4oEYf>fkRI;M`~H($^r9}51p9Qk zMq?EOtMIetLJVH(uhEp{^WeyRgzZ@=pHL57LlUvv*WwDGW0-jJSrEqg1uA)45QjG4 zbBJT-tBgmy{NcCp-h`e!4?5ceQ|9C!(v@Rw$OeaB)(JAZoqpcI{#b^x-C&2;j_M&~DhBK3#64 zAHw^*Kj4%Zeg{`d`C7cz zv+e0m`EUSd+F9iJw}U*lxrU_HNZa}!`^lAvFY}!gJnMc(!kLr6JH>x{*1d^&Mql26 zxZ!-tG5x#19aVn5@3*+?5KbR!$@+BD$uR4e>AZ#M9gF8Ao>l!mV6Vd8HTa9?w^nyO z!mmeN`u7L=kIWWjdy4~cNc{C;|B>P>99nyyq28ZI6U`)i5Y6&kUGL97!jHn*qc|4@ z{W}0HE&}Me;@tG|VH|EFe(1O3t;kp4Q-s$y$0p%-LA>v$BT#%Vk2TN#K?H0p>EB_x z354hvAFRI{kT&bj+Wc(@+x$cw80Va~lLoYZ#P6%{?h)+cBY!6<{S9~TpUe*pkBtsr z9Q!T_ap&yr8Je2te+gUw;o$;(lLG!tLYkrBJe&$obYm|}{_uU5#N&DKvC;i}x?*x@ z|7i67LF+N<=Nf3ICh*Rsc&nfY5#?zjf1rP2l70k7x-S?*2=kF|OH@@7CvkA2CWH@- zj`_DXn70Xg-$7pM$m3Cs{djQ0_YIFfFxA~N+`qqjJVD{>ZWIcH1O0iLdm=9v<$HVB zCdBZjE&&k2s~*4ZC9VvWk-nT zQ>6KkvB@b^;sh!}`$SieC%j#GL4Im*di27)6qt46TBWXryC)|TZ=`tmINF@bHF@0x z=Pa9^bP75!`|~@{cPEOl^qeiO_ExHcb5-oOuvx_o!+9(UtMHJs9$Lm5eIrX>Irht6 zPIl*^q_TQqXmu4gC(HDoMH;yjA(>2u^i zQiN&1oQ?~ID|2;h9;J@k5RMs1n#ULiYBT6ZaKS-&cL6p5dz|XBS2SqZjbPy1kRG1cGW-GoBnI)Qm3@E*Dr%Fm7IYj=Je{01ia`}2O7Og8|0T+Wq$%DM6w zIds9<|^!4dyecqw;$V1zi+0T-wLl6 zvY{1?YVS&2ab1Yf#%Dz@T!ul+LBxywgi??F1UFWO%Ar2v4~0Yz&%A5A0=HU82x{h$1F7;*VsY9(ggM^(c}-osn(*Yy`hJhrce*WX9%|^Rp&n$* z|A^b^eH!n>T95CQaz*R5IA>yi^YthitVq{L82UQ3TEivY@>H3V@OJ9Syb^H=x1XiW z3GaaZ5$dOe-n0W}A)ze~>ENTaI#a^Es_IeNIjW+^^SKpy+yWhE8NTCKUdpELmwcnq z@PWQMwY=&3qoy%}T522{aeaMI>uZfYcw@xJJ>GcE_95`LbG8p_I_FvcmXgKe|2E*^ zD;IBylqz-A%X|bdth@A+b%Z))JFB=IaQmRIHs*27^7d%j)UQM*U)simQO|y)v{YZx zLow0MpzT^+PknygpQUiT@Vw+>K^`zKO^*)sj`j89#jA;-QTo$L0(^Z_U$zbD@DF$N zA9=Uthk6`H-?97(H9gZNU26>Ym8JQmT-O%kyidkpj%bf@rooBksSed6MoWU$_Z{Hb z8OP%}Gake9_f=W-vo;-Xtj$`iy!3u9wF$StH z6%I}^H~b~?z`2+*w}alu?>+u|GWQzuOYD?de_7g})U-`!!gk>J{%if_{^YOln=N-2 zX)%|5ir>iZO!|CD*K5tLulaZy9(I>i4i)m)M82Mx-e)wuSFADCwn^@|cJ<<=pi(OW3RA@GY)?HVohD`tkTc ze8zGc;+y=zI=S7&@(9CsFh9LPp99o&JRE6$l= z_A1WiHazJmXt^&0ed?ZUumlBTljF|Mqu!Q+6ttzQMFlF z=ku>iy5g(7e3U9J)IZ-kN1ir*1Gv_}>p@{5;iDcw3msu!9D;x2uViae*<`%tIPQq*SGs5Kf(y(J$*i2Z=O!q0f~4$+=q=e_wZiYwxBNq z>+SE5HrvhgWSn0eu056T;+cBdl=dUMRpDM(bz;ASI?LW4%M({s8#c2mXh-j>g%Z=x>s@ zwGG#$VLjPf*V}~oaOE(B2RrBIxbttqpUs0!X&b`Y99@*|78v^j`_*@X{Gnf6IC=5p zRR0Ks`H_BPB@Fty4P~aQoj+sj0&nJH9N}*y);P}T)k^sw+=~bE7xrb?#MD;>to@zw z+uT%Pp@9~16JI(^+?ysX+JSHg>2i=9%^#TWalWkN0dLIvfJfxAzI+#D-zqjOP%c)x zak0bq3-T|+E7Pvgl_P$;#j)(|@xK?;*NRJ7>QHOzt$*arzx!ILzYf>G<~*Yf`+BwB z9zwcpf!u5D_x&J0547g@_YH~s-P1kQi{}fH;T-yn&3%-U0vR_UuTpk`uF0>*iedS) z=r2DA(!)58`>72gzH9q+S0- z@>rKX0d+M#FR9~kNDdI0!!b>5{1Ir7|KaWlsIxeu?1!D$R5I-AD|J2!2S(~R;eP93 zq>)AYam>6Dx!8ukHpo5U7=m9T)JuchjG1wKVythv7rSbxFQK;KhBE{qYo2eH^38z{ z(_|Vn8ncm0LUW)1ChG1#- za&fVY#_B8LWl9*Ec{@X!D`|6~G$ZiCP+Gy`n)a^dBhogaRIAokYSA1XKPEOE z--LI8-%{}sJXqLMDg<@}JH7pq7p0LKi^KipSs_lmH+vcDQSjU4Mr%H$i3(iFMDpm~ zEcT?Lk`T8LC>&lX4d$7B+1~2Wm0G3$2rfudqZr_FSR;_a8c1wT$F<^7qQQX3UK5}U?YJ%XJhuzv@SJEZKBWwY1# z31D|-yD9d-S`wR@Zk+qT0)JL4Cw)86_uJiB-wLSD5-rCn%e2#p+vCgG$vUEq6jr?q z$$Gdqd*NJPai+eoP^|VZ^Bm9L0c1Yz%lbVOW;edKi-z!N5qEzUX4Oly^!Dz-t*<_i zh4m9&kd@nlXr!=BA4J=&T2H~4q82&o*~*)B|4`OEBy>F1mkRV!Izt3?x$JEjOATYzduFZU5l?LYA7v#GA>%;+^{@9 z18r9fUt4#IhTH)M0p>;DBB>VFz1_9OtgM&JKpV*OPmla7flaEG0JY-g!$NjVa7 z;i}&?`1bI7@F97EcnohcRK2c0(rpso30`ph2$Q!)3g7=o16xa68&%6r>FepV%)@rb zp)l_pTE@^^z<{Lf8P`|ZkNq-e#~tpmWqj^aX!+8(E}17Ytpd&Gn`QX;b%;!J*Ll%gN(gZzw~%W;>++F&UbBn-=7idz&@RBa(VA z$~FlFneRvBvqAYxr01FHA{jbZ#C!X3wl?0);}YG-tb^tFBL7XwKa?HN4S@6h?M%+# zxZxjk)(JTSMO?#PqCqu^GN$QDFGw#}iqc58l51dmc`_X*qCBRH-mGO?Lnn!&$o`R@ z;ftYx8=K(i<48B(#Y+Q&JNhi^>xn7#g(3FHFE)9Zy9;&1+c=9j)PrcEyMH*kz#$&z zN#Zlu8x-cmnwJLrv|sS%oGM?CChK~Nn3#3B@#_rXE&lxnOz7S(gWnsE)G@#!nZVB_ z!ap?B7g^(*==tq#7#5X&erQ8^I_zBwOo{#w(yznh1G&h~L!z?}!nar)7$2Lyhwo=V z?}c@1yf`xqR~*6IhI7=FLbZr%iGDpNkL?l6%OLDuJ1_?vDpf1Xdx;x2V##iazw z*C*4zjJg*pCwdF3UNsTNWqr&=_R5hwm#`yWgv{%`lu%vh*EY&vE7%KTRf5c-w$l`2 zEA^-!llKwFazcm5{-6zN?MeKVA-=%|{g~kTiXJ>wsTJTNt_bHKSl1RS<%Fz!Rf3je z;!Gx$_Ufp-%v&t8USsD-Rdhf3D=4-!K1xJvi~#TRbeIRdlt% zVj0Kzv8;Lna^IVogwTa)1r^1)Lwr1Ex>r`viE*DZp>HSdfd(88ox?mm zlv$ZvEG;GG?jOc+YH49s>4*q5g>)HKPnRq4$7kOga`BX$;ijn7#7Xj>`yxh=iYuuo{y5Z&Gw^|oh++$C)ke7r`Z4Lc!q+UzGGcS}8c_zCJ<-GTu{BF4$U8Q6A|RDQ8nJ{NDi-sI1FxZGzpkB_9T8B7zpXmCp8`=<^0 zzNsaN$39Z%O>cUf>P@Yj5Y7|jw*8LbbBMpjp02@i3OQ|nFt4B7==TY_0Kd~~as)JZ=+v)si8PSTJ6M)Msot z{!RtYT_#%uVz)>>D!a37_BiUIz;-^h1m*FHFZ;_*{0{&h;wuEx+yD_ ztIE%TYcyY>V=Awx2~_7g*UPTv)n z?pcW2aUx{L$#MlQ-=$qdPT33?Z+i#hXv^jUbF?pJJo4PS*=lm2QXQ>f8u0O-2cBJ< z`(|K!VFXe~><2qG4?-6w<5`r#!TFKhpf{i87-M>fkiI>*Kq>*mU^Zt(oVd{A%4LLAIxEgpGYwfSHH`_kowF;Tr1 ztAQ@#Y}C`$o8yVy;!)nbj_noc1$<+&Oyqg}W;`VXYf*S*U~zQ@itF))%|ojJ1yu5J z-QT!*lyWRBu%dRqX>(GpXBsze=7!VmbLti+;B(7n9R*PR!!sakzADQ)O9)@uX5PBl zpJRl!V64mAHbdUkwx_(*4Owe9>cT#^Z|35!#c;aRn_s@nG!nCsO;?t$GvHT z!{hx(fhfXTVz^gfApbnaG#&6Bq}h0Axz;&mXuC(5In8$OT=3hNuoqjUEl0ixODJnQ zyt}NhBM}V#?K}(?Sw@HVlsybqSq8(q5ekd>;XP%6;eiL3;K%bY-c%O&kt*C_U?7HL zknOuw@zBqgi}Xes%ACe|>pE-k&=Rk0en!TV1^}KM(yr#!X|s+uYn?s+Ph$wF|xUG80Ln z^v?^@$NSr(!~4Z`2lNY}T|?3AX!FZn4IzD)^@O|S5pF(sUxPT@DUWbCKBfUl6c2aE zBV571s}+^6!}(P5&|-!kgHAMvdL9-@YA zhJ3*pZE3zVn_tw;<|FoVt|DIscUu21?z)Eee{m@zybFt4D^uM=qxtUf@xHMU{Nmck zzWBd!KNk8jv5A<%m{{)uEM(*L&^g-sQSV0i`l?P0I{h@-p{LnTo|;&z{L;#K@qo-D zyff;wVGYEwe0+EEqlk<9d%O!HB5bG|xC1!M_4GVcy24}aU_sKo2xZ&~ zOK#dTKxde}Sn9x6X4e{T_?^w|(s-UXs(W|`sDJdp5H8B+51fr=LEkzN`ce8{;G9i+ z&M>^IA#8fe(;Db4Z1ff;{X2Ev^HRy{;km-md|_tB`&uGwt0TCAGQ6h}q1G_1|pI|-1LX#TcsD7A-|EIn8fUl~`{=Ro^fP^Ly0Z}QT2#9o05h)2t zfM7^41rWtcNCHG4gcOP*GPW7VI*!iRb?j~IebljyZR}$2*!$?%>+}8Xv-iE{-rRum z|3B~hKJWkGe)7vXXP33tUTf{O_t|HkecG5cE->I(d(dPi$xLCL%$k@W#S1}^st_+( zzha%W?6#Ubvg3szyOW+wQkl(!v@z69>kaC)C^Fzr;h8}=`=~V8&BLUV3v7EQeQ-x& zZSW$(1}ZIJ;UZD;}Y!-=jsg2%WU}aT79coX~ol3X2qf?gGg;C7PBcTel2NN z)~${*rL~-my_|W)<#(ft=T0#m?Q|!SfwKyyaQx?>1F3>(TMVL0Qt@ z{VvY)cLn($GW9lt59`64)T4wg*FqG>hr*sDtT_~R6?r#Nc3@FdoV5j7Gey$K;*hRi zFirMV@xX9&r>oh*Dz?H&9WFbR?zJ{Ry4N#9U1z&%w%AR$W`OkhpPb#MvJHi`K{qke z@UkU5)3C%g9uw0g-|}3vTrR_4543*ebj-m zSNJopkCo(;K9(Zyp$UENN+urS^E83H$z8Y72CEzjiL46Afccb^<)r2b3#+!1O%?u3 zJgF{?t}eEZgE#SaB=#b?o0e-eYa63hTet}=i>TH9i51Zlp`tIEt6iOkKy!ra_X6Ko zU$vAO$R*8jU!!pL$EsRtr?in^qMa3CPMYYC`BTZMlc{B{n-6#LqL%+giNdqYqFnma zn$<~VD6X52ODaco=ldQM6U$`nRN;K%gK(cAu+#@pZqUt3)TdIfex|> zLkBCuVahwuL@ASR%sO6_7rm@;ftF{bLofPJ%%bMS!P zd_3)F&!^H(G||dNMzof6h=&}~haxN=8WZQ6=#mvad8o`8*vRT8*mE=v!4`@LqbsXg z8jXj`*OwA*!=laF1w2N(+|YH_@^w46pQp;3=fWD?xaax z!A8j2);IB?oj~?#OVz|JW_D8UOS+6ON3qn@H#s+K!}Jl<<%D6j*7^JXzTQOHN5u_? zT%BbLO~Kr=o4gLn5`Swc%RRY@`2dBlH__(0nzj017uAlZ-$;5rabeuTL#ufBQPh){ zUKpCi*Yf@j*%9XF9WCFYeY_1v+-{Ey&-=-&!w+7f;dvF$YIzeWCht={Elt~o$~~QO z?W|QHa%8*MTIUN6MW<&QK0R$)p!L%+THmHI3ZeP%Y$Rr1;_JtFcx=B?g_}q$eZn)j zHu3Or-cFT1GakN&54V0b60KUhwp5EYsahaA=_V@@wZ@dca)sqz{mn>9T_5sM-6Fo1 zp>J?KPY(ToUq>Z6d>th=Hc)wO7)L~_g7KjGo(MEIglOVhQuH!g>U;b*G=q6F&7)~- zr(ZwTqWL*5`65AacCO8)NjFDOwofBDiD$v5(cYd%kw$&!(K>F7$7#k%-=lPa)6!yl+g8tow}E_ber?kVxk4Luo(*db)^NKv zbUtCbx-$G)3x*N&O-z9|G{wH_u5w42=BCBty$j=^v0IOzx{ou}i>eykQU}Ms@{A9K z)2G||YR;c~fXH7c+y8P*Eqh@z60Zo3IktVK8uPVGCtJD@T7k`{cfW{p$s7}CWvrpq zXQky8v-Kr_xis4FB_+eZXkOxI9+B`|xN4EtkNR8gQT@K=FT z&GOh{@lct=6c>74s=j=bS;H6h*6{3}kMFs(3Lj&t*uo&_5WM|lQ`d1Jx%hCkrSWEI zSyOdkUA-G)Dr}++D`{?0ptBu?=h*N9y@zi!_SAjoWg(kkj1pE{D|!s}?6{PCwhhCx zo?Toa-J;_wosPY~(>i(CPTZG8%wJvFt7B>X{?UOi7oBTEaq>SZ!~5LpT^#RE+wZ-p zj4&@ZI{G)oXry=deg{&YPhh`JKQ3j*J^MX9f1PS?dFdsScM$l7gr7XM?O)*?g6|I` zgsZ-tO#ID^Mop)N-Yduo$CdFpOQ$2{>z4fPhFjQO?q1>We6l}+d;em~?^N`PrQ7m* z8ri(dP_>Nx!xq=B4X^VOPXqn?7rC*|kXWI4UWORAHYRwE4Jl-Gu$4X?5&iq-F2oFPLF@ZWbBwITi*m5i?*5|$KBV_ z4j|gb*}Cr|RgT6qx|ZJy_xX1?8~5M*Qd^Ns529}BFLbY>qunE%^LRVVGHJhC z9mP{zUh(~l9&u#`&*WS3n@mG|KI-!LahCKb zNUy#OJ=cAlbbc>*`8LVj`?&rI`fF>R6isM9gk7YN<;?lcc&S0#+RO!~Q`|CDty}CL@#cy6>q%o%P zkk~Ae^BD@yA>7X*$tS%>*&A(G@OGeli27dH|NF%G-^sH7qC7faZGaeleH1Fse&dj>jdP2%b)ao&u`5bzWt{ix zc>Ki4TQ;G4Uw`i;8IbLm@AE~@yYXZ4*kj3+FB#+i^EzSe_!vGw*-BM z+QWZktHOUF0O;f2 zo1%?Or7(bzJ^uyW1!2MbWDoZ&+UzLarj?uWY2~sX%~9r%Qaq~d=vwr`*GwBFT+2Sf z@w#scU#rg#UrRpz`etWC5%}Oct)s_`k1pnYAv?xMkB2q$evb`PyL9Pl$Gh=&n|Qj~ z(d?a|`nC;)d3xSP>l19b&7NLHJYBP=ml+BZy*|i~??w-5Pk5GzMn!>rjqEWe zNseCk^>D6w`)e;pf9>Vyuf3df?d25ccEz6Kq7q5aUOEQ65hl?EVVz=Oh{^ev&hap+ z6{OoP9u~_h{UKxM)yB&B$l8xBH%3q2^a;{QOaZ+vF?!9Go|jV=;mj39p*3Pf?(PvZeqt7s<(Vrgmq+XE z*V$wj3U9-6J2u;8N}G?L)CBjX3g^2LS~wBg|3zUu$Ea)46l6oR(SCf&)l+dNmqBb6s9Tw~f%T6>TvO54U2$K3y1o_K`S8H?i?z+63?PEeoY zU3qyHFxSR~RTzrrnSfpM&|2BtcL(vUl+QDQxvFDGZ86?>Rxmf3s5-k=a%Z}Zp4hVg z&34bgE9|58pv}l9`|%IytdI8NAAgZr?;! zoU@f)@X?MhrB+r?<#nuJk8av$q<4tFZp^9EVl-jpP68fVdES{at=f5C*M5CF*Ykhx z4>W<*Pw~zN==pp&ZUAwTiEK!9X54ROvdUef>V)fvyY}fx7V|@TCK9H-TTrg;@71S^ z*WHtN9cIgqj|qm`JdvysE}f+Z6XGnO7s*mNL4O{Mkw=r(m#w2l5MvzO;5t5EtoQH3 zKJj+PvyLibPg{QAFO^p1%U>#PJaM{@GcBJX2lu*cfVZ`8pGpQ3RK`Z>gt>I6>3rIj z=$3JJsLz!oedaYWIItbjoaE^HeH5ivWBi_8e))Oe(}FlRm*MQ%ueF;3onN!oZaX)( z8T4~@RBqd94*8iws%>=dk*Tase%{2h;e3YTSW9fbM_5|9CSPxn$WJSrZ?*bw9Qr6r zUvcam6N{_SV>i8sspCfFP4C`=b|X562fiUoP0R12G|Qz+ z{oZ?YUf%3-`=&QN;|LbJJ9JS;xE|>V6ZiTC_WF+1L83lezyv!v` z`E-=un&+;?lYW{5Q(j$r`TBaFOufDCBnN+g75J-&Szu|Ucb6Yi{1BTy7$=Ih_MG-} zE}CNy)X({PXu_Zp8a|E2ZHo8v5kWcWrYe+1V*{np97vc>jjNa9q$SOF_&Jksp2YHb zo5#|QWMz|!HsyX_eC~NVn0P_;Q+XN#i|=JNUs_jPD?XcJa+(!{d-?e^aT*b`GAUkZ z!ttxP_U$S$F3mK$w1JG`^Z3omvr+r{x9iT^pAp#N*UHk}2@~Qgn_0X!yg6YH?;s?n zmApAQ=Cy=&;HT>Y-}Qg;8t5z}vj#b}sJv^hiu3EE+w=5(E!X~+-I^?EuBjKtAt>mc zX!~EU4^OR?EG_kt9MU-1gjTsrQ;m~zlIybt)g|q_9Lyq1E{C*`3q^T9X64XmZ7bdM zY6?K`;XFD`4A+CC%4!#kUVZu?+>r@|JNh(k-lgPCv+cWgG#e?GH^A$t&nzuy35U7# zv2s(y#drBo*NgRMjYSTO=>v7_u8}<)}M&? zKjtlbO;|C#oG%TQEIOEliabrXs}f_4P5aEXhz{hrXG$O4*i=1XLVUsEoY-j&F=W*D zyi)mgn{QDiTP^s9B4$p)Wh}qO(q~AfM*-|t=U&!laXxgT4YzA7&gNQvUSmk5I}>z_ zq?vO#>X$06mm9ZtHSM~l)A-LNt@5A8u|;~qeV^g^Qu#`E0qJ99!eK(0jIqOUS|g(0 z_1K8%#(Ff%-xr^Eq1Bwvd4eR6;r6_J@E5{2Bt{UPo^~PO`oNhJMlL>KeYcxjdgVvekCF zyD=43ubF00MC< zqZ>Gn@kourWhcjZ{;lmo^F~+ZO&ld3$wBf7mwyXk9Yf_SPUQ*qhYUP#{$5M-2tRXw z*fMRz-0t$(GDsKZ-P`$d*m)QFzw1bws7xapHrErrAt^#_;by{dqrQs{90>5ZaV?J@_mVK)2l$mem{mPoUC45T4 zHo@f3P&>LC{(U>rxo=1Javp9+_i^oQN$KtZYDf2T)URb++?Kq5{Re5)J|5uMB0b^W z_GG^*!?%lvIggbIhY4k(!*HCpyGxvZ{X2OLHX@sPkaH_s4dTK=vVJck?IGf=pG}sR z^R15%pJbCZ4{u>^)u;Z`^3l?cq|XfO=usD+ z>-H(Gy*`xg2_W4*%~3z^3r5j*X&l=!ZNzMHX^D5zTQ)`x1+VSG{_^sCn zbIMSsEkPKLcVl@&xolMX2+H~_DG$l{ zrI~*buAkbG^7wZ21?Mq2kuE__7+*Nf+xgS3U;l)>PGQ!zKjnIZ3y`hrI?Bz4z6lV! zuFy+Y%do%p=JQy7I}}Y0tJcsnDV?R36y_+Zj5PCaXolNYsIQ;ZwAPM0(!Nx=NqxF( zvNN{)6>X&_oI8%wv_E{pdIHOHnJKGImMrGrJ4_@^jr8Rd_N&md(Xv+XQ2w?6w%3m zE^`C1n1Hch?Ki55WV-rGMy%QL_y5Z)8`-)1zc|<7pHJ&vfK}UbrUk3fEk7DZ(@ylA z4?D-PFEcLi&TFm4u1Ci%BOO9KWt)LX^ELw+ne(2JmR~eR$FLpxRuTmB5}G$lF}IU2 zZ??h7{uFDYspnHP|I$XX*2XVP!q!wvw81+yo!~o@-nYipO=-KCmip41OwSZ^GMfL? zoJ{9X{d>i95>sJ(>giX^f9iRvpXbz?IlmsVi!H+r8C#v_Tns;&=gbQ6(;j`KH1-6w zjF(n^MY2FQVIDD$7>`~510Ht>@!0lP@n|h)>pZ$Od48U*StiZigz`sCwefZ)n_c-*J%DVMVmk-3A97LtYtVFv~!y~LDT!PogMu;*Pa5I zwQL8fFEU%PxGvcH&ikyMd= zE7#~v=0Hxd%eej3lR@pZFZTDJ_^&>e*F^u-H&p)ME&H#r?C-Qi|25X_^Yowa^Z;^A z_No0sJoVZ#Ph&=Hg{Lv20=fMsJPo0Jc%C$0FF!vZ#1r=#N%PmK=j*qvWo5lCcKSbM zE$b>Aers!471!EYR>f^;Evw?Uw3b!zIa+Vpa!IoF#fs1O@hR4_D!#R~tcu&xTGm}d zcHi1sR?(0@@_V}Z>rwb8^_Tuyefs}Rd$bKkcDG6|Nqe*@e3K8SFHj#mgs^`(9r`Wl ze0cI6ZM%^+d5<>9xV1gn6xZ4wZHjAckG7$dymR2^jTAQ$Xr5}6 zLd`WSdCy2)d>n!Cr&$RaxY35$?`aLV{s}^>?Bh56SNA4Y(g1wdC zg;ab;pq`zI?0!p{R~!w02~~9SjbjMkkQia-A;%Ivy~ceJs63bx948t{bApmBYo{Z7 z5a)kcNhPI{t$${s_9&Ue@7W?|FKGESv5Ie*Cf)2!8jT4wF4UNTvGwPE4X)_v{>$f$ z)8-8T^68$bd(UIGk80xB$VElqjlR#mn!{!r1yI+ z$X>$qwT3%2Uwnz2eBREK$Csfzo`1a`UqL$me!tRqs4jxiYChVSwq`DA84KgK?W;z+^D$p?%FF#@w4szNdEcO@@2(*m$j08 zwS#^2muq*GVBGPAsSTj~_Mufh_(*W)G`sm6flX?1;aGjGwdBL3b;goHC zy4$C!k-TjTn_00xp!`9EhSfxv|79jo4z0|lAPB>o>eNgg)hU}gslImKv7-W6NS?ku zD{d`m16la@!-D<^-PZy>+_u?KUjrcJkz)p zh3>h5(()|~yY|qgbm6l5O#kkcyU$WsmRVY`ns0(h=6c5lUlrLH;+eIDC36Z&i`W>y zKucBQ7dci>%F|N5p=2rYNMA=#hS!&5CyDo^%_(jH*BY-#{`JJDPG7pcFjl$iA?*^| ziF}vRh1<#RR0i~pb!GWBse1oR8A`8xN{%Gnwr#F6@MXuje8;Kh4d+VL5GRZ4C_8gktxA^`@aesEa>0D(5vJCv! z8N>;`PU_drbk~8uPB(i||9E_SznI_R%S08tu`CMn3 zrTPdl_bI`(_7|$PZ92{NpX?vZBg$n(HH)>5KiynJ9v)8xyYAX&;_2oR!j{xD1-n|g z@$RLB@i575enB$YZ5y7lXGJa}-2Z5|A&It>?`Hf>um+;MWZ&o_o`qEx)k8n%Clpr2 zTk6a0ciSRH*Y(_!?jLt`T8w!7zW<>m5Bc1A1UF|;IEG9!&aGH88jXwWTONmgM z6F(=pZ9msRGw?~lni08KwR!cO^0zlA9{+KpOE)NGJGFe6Irac$>Y+S0D-UhckAZYs z=i8IwZUMTdyp^MVKHUJ$Q>D8-md?@M7|(MDajEj$>GDX9>VqUl{X&v!AxF>0-&>)1 zx1;I($R5~6Jv3XEA2Ij3v@PS}Yd0v*%E~`u`v-Z3Zj9IMfmZl<(9!n%rsg5dJlrY| zabGsmt-HI8wDSLdbH}^f@g8@)&mHe~$A{eU5qJD2N9kU5knUA)$z1w=3?#3ulZ;!7 z6CW`<;oQ$Jc-xYUME@yA!`f3Qo#G^u*67Q|<8cu)n0`Y)uU9)B=i1UqO8YEj>gU&8 zZ{k|~KF3k%MK?y94;^@$Nfqa9G*w(!cgZxp{!``i>w<tk5@fD7u zlPJqH6D}h;E?lSNxNx14<2-Mv%JcR0e81-Sd)*!1aK|^@aWhAsHaU&rq!Uj=c~bjG z>kaIe*#aM?)3_gdhkSvLY}-}#nn|Ca{eCrmNXrbJw-23n2%UEfop%bIcMhFz7dr2v z^S~d!OL>x0Vq0JhAL077jEk6yogH`JTWMYB^&cf|;Gu)HcaL*j+sN0A>6kR82(AlO z)HkiO*G~}7F2L$y>>SyXTvuspP}lD$&(lg%(=@xOp|nPO!pG^jAo_rKSVg|RyR2)` zB41&nf|AmdmoIIuWC{Ls6c#Tb^(Eeg@evj?)LI?XEOhtNwftR>qLVeiOJ0 ztB77D%&(c-9l0v(t#H_+px&~3pKd*2O80gsOz#S5+$kF~rcQ5z+UxhY)_O-)X4vcZ z?R710r&iYnd*!5=4_sKT)1&Bo7!Ql-OyM8-a4np(t7w99Kepk4o|Ntrd(G}TPA3Zc z)P_~XH3$CkI&gQMi2Ij!pbf3hUz<(3wf0?dT zgvTvIQ;u&$B5)7>%#WYGf}R`WWa-@Z;ooo`?!&+3+P77u`xg-OpS${3CH*Zb4hiFh3I(w|&-zavipPtrsQ~`jzuR-JYs)va^n9O~O25$b`jx&l zzRNT#?3Zt(?@rK(i4q-2m)j8*)^``Kll7eygeB;^D`8=MONZ@g$2$M8>%Aw}Ubjlu19T+yP8{`9oW^a6v%eJY z){P=UXqh%*dbxalOls32|5R!FxU_!kkeX(i$qw-*-Nkt0+>fza(oY-AWwfN%#_a0&kp1h~$u3;$IEbU{U;Infey&^hSwo0RO)uT-7NZyJA)~TA zA1%vIH@my^Ube0C8ZpCDq*eNsbR%Y@OPeb0S@P)T=NWa6;hz)TL|lIx7mW8}_7rJr z#yFaquL$4Arkbzt`X5Ig@gVwf9jBQ+Lj0-xSUHsK_1`Wty{r1rok<&Re`@d7**fGl zEV0{{2m4)IPguPVV%+1?4KwpKV_{QjUksZr9%T2*uwmsjym!vLNQj2gi}xj>fFJSK zc10#-=vw^q-73By;M|4_myPiGz96tDcn4DHC0{mM&^yn;1}!eVY;AGDT1}PIHhErV z>s#-QM)_>~^qN={Y&L6C5?e87=sgtKFFwt=mYQnIc4Aza-BZ)mM|pY&d8|Z&zOlXO z8-$g(SGsNL5Pkb$W}nuTX~Tj76L?|MEM~p(*_6MoQM+VWKKnU7W1)`6{y{jqY%Qu` z@p3Ge_IptIE}xf9GG9JCK{O%0eY~B%tmJWm;s#JAqdRtuWIu;0cJH;D!3BIeel%j_ zW8^EVH3AON)1vumJDg0EaY0^LMKW&%tm?N(L-{pMha~Li;fC8oOz{H)Iq-&Yb3>gQ zuZF_)PH>Et_($jN+i$Tb`=06GAWngH=*)Htv3x^=xPrA!3|G-msx*!^^{lOmQEpk+ zSd@4i=J>JqWg*^2gu`Pw0=>F&>>ZBH;>vL0)0nW7cv{rK*`C+8vf6i3LNfMowwZ*& z?JDgcLxQ~))vT>$TyMWl71nhb)0Zq+XsIj5Lpc-5mUWde%GK3vGN|oPto^nO_xF)8 zxp6bg8y0r)c`<{*E%F_4Yi&_cShBC7%gLf7}^y7D+mQ*17(Sf`IUm0s@fqzw>v?5xM=d;d` zM;Uq#FWrnKPiWvoSVyDwTD`J@YBk`Gcu~gMkq@6$wr|b4H7gtV*j_?7H+#(A$Mbu0 z3z}cxdpwQY*oQr4akr{x3h{jLxbS}W@px|{jiIt~tEy@m8_W36lHG~P&Ug5-LMEEP zFOOMpj}l)ZZvnp*`Q-s?33Kkia{yn9`KvVF*^FFS9U!ScJb@ouc z^V6n#xmg?;Pn`eFOVE7k@w3JVe*CO+KYrc^I^ps2M6NYP(S487P2gJN=Si+SJy+G- zzWQzLh1eo(BtB-*m{Ih@_e`RhYiTB?Q@FqP$s;~oc6iQHS-;1HZnwT;u7dFo}a^F#D^ zck?<0p|ArMXdOYYcfd5l{cl*9a?*33R_=rC6k#ySQ6D?canFfnK-=q6=U$&PIS=b| zU#`85l&%oyKDdaZeyQU8y@S6Go<&;OLor9`RAq#9D!Q{ls{7zp;}|E#;}Y+K74B`J zoO4}UzNw|>JJmdg?9$%{>%O;yd~wN1e;H;!!ov5xrCc*!h|TdSO<53@aNk=&SlF(l zGtG0%AzZ&;o+DJ+ocOtPmUw5v$(sz`j^sO?(`c^rWAeFvbjYHq@xI}#`-0QoBb6wkd zP-|b0b5qQFs6Kr6O^@R3{f(|!uftj!eK$9l2jP3uv3Zb%(DiZ-`n(LYh_J9dRB@eb z57j|ff;}uIENly&$bi z3Z6g&PAVw?OQz42{nSyew`HAsTdwCkY|E>-_V%fCD}ijefunw@;`}o&Z@Z18WlG01 zag3F{G03}`FwqTu@n?WaCtke#)n6#xT9C@dTaClU<8g^Lu5fST>p9o8tsmU_`dyI1 z#`S#5`!sLU;kmtL=p+f=j%n5qzM^uO8}ntDbzFz-{1C2_?flRnEWyqXBP?v^vIW`s z2Ez3V=KGR42xjo(#u2v#`|R#0=_V~p=iU~61HG^<9Kp5Mx6*CoTDEYcE4O7_d^{mr zpxKzCNUP(~9HnEG5!SKj{+6&*I&L)%9mnGmb*yl&&=fzPH?oPH@>-` zL2sz_>NL<*EBib~n-~$>h3e5dJ)f$GCWVmOw)vANr^80Abq>~>25Weu4A%89N%K+Z z=48^a7f!JpnaV>~kv};8s1o%`rk=Vy?E{0PV{1wNEBnCwk#fCF#r9Rf-cEJ=XfHYW zmE?V3P9xs$x$-B@|EKM_@@H3n>0?WKu4oU!G&9@k{tWU+_o>IVF$*$tVyA)4$tRpe zUhfmm79D(r^rC0`iaQ5{+pF5O!hJgRow`0RMLN+7`P?!(D=gjqdze0ZPOw#JU>0FLWD;t;cMS9$X z{MruYd`D+POz*)x)rEw|e3iSW3WxP`VHc5ZQO#n_WY{szC0y5OD%#%Lr<+T;Zm3)n z^DaydE;z}U%pLCSd1@QhxX>Lghk~w?fOgc z(cWCEu=1E=jO~q-m{wl`3KodBk|&MyLh!**1P(Ov}m8L?IyP%92ANY{e&lhcvpuL8ww8qqKHKa4Q(~#Q2E$|{AA|Ir4 z?}KjRJnS=W=i0XsrMneqT=F-L`lX8V>#OV-l{9ydR_*>yjxEv??w|R1zPt~(oAj|V z;V_|0>^vOj+oje-C+}x_7j$C6u(pBO>s)1coj=ZbtV}peC=;EBW=j}lE8fyEp5x>{!OPsfmhV9!j%*(`W zXc=jJ!K=h2+QklOuUWb+bt>JoqaDBQ;zK%ZNqq~t3HLV)@c*O!=1s~@?r%0bek6_F zTj_5`Z*5;5w^vY@N7mE-M?Airg2#74Jnph(9!KxJ6&^?L?fb;=K6e_G1@lJ1*eJd~ zTzKCg|4#6GA%1wjBcTH}6^YlBX1~{? z!$!t??tW7D1I$9U*q=}Dc>SmQTzv%X*7mv5yK*$I$j2c$@Sb^NG`6o5_oSgK$sqN6 z-ifkGB|G)^pSpUc-b2rBp%;94f__`=Tldj{EL!f9_8GLo`=tGgYrfz7-`*!p_v+dw z?emaK*ry~(nN}_d>XmF#e^Vo|UaibM{3`mgn=j$Z+s#*;%Wl+8zvjHZwVUL3=Iavp z^xxC?hV)zep2oMN@jvb}l6VZBXK%^Q=OD}YH>^CRf*G-W)PpZmPnb|JBlNhjB7Bw8 zA~k}(+1W-=-x#$#-Hpj+6#oC#x3TrE-S@~T%(U*=#D~JWF;8w6_7JAI>I~kC`ynLP zY;wkG;J(z21d@WNH2GV3w>8v4Teer(%ukf(ZRTgrWi!PIGF(x)q_!$pi(~I2d7lo) zK>LdE5q!ZT@U6c)v^&x_{G z*te{FUt}7*lNW@|DJ_o{m6Vl53yY_fxVVT*Us76H!6y#O%5(GfmCltfJ&3C)E-Wro zPCif{ttcz7?-$Z8Z8<@{g8XQ1krLRrwn1EBQBlG4+#>nz4EsK{=6yQCtIb)UcmJH~ z*-%=K7)MT}@6k9?zNRyIB?C;v&WY(-vi-m57ahv_0p~}!ge#?ycV;9Eb1C806MF}qyGWRr$Fv{AGIjJXS8Z&>jF@M^Q zd$;BA0Ns6{b5aF#;O&4J#ta^8%n75}rmQ7=Zk!$5+riADQ(*o&!pa8NMRe6XQzC8;5VZ96H}ZyZ9i! zr?-mx8Dwz)dTbA^<+G7H^&Eu$@7kaBw3P84Xx*QCzuV4oY4#aNA*ABY3Q1@pE zzYY2Bfc$q{LYtu;A7Oi+w1*yazN~=`y8dG(ZHzjMo@dN#%9@JJ9Y7sUAnZ1-AEKO{ z$=iMda-*ElYdP=OZ+O^a3~dS>d|8J5^y3={ z$YKcR*$dboZeQ$(Hg-AZ6Dey(J?q6g;|Gvq6?U=*VZVj%9Z7fTj@SY9e-^q64#U2B zFsK}8%!kC+QHLUUyqi2f%|KtI`*;H7Q(ir^HX+xVneYlf?U7OCI`q=cm@AR>9q{*3 z9{WNx(FgB?55cCgDB~z(_dU8gU_0c4{3;r-J<8ZLjx|2ibwA2FhO*Wp@4sP76^9~2 zbbSwcd}ShYH|RTxtRFy*_rl+M)cfoV+QWXvoJ#s{C*kXm-7B=a+mPG8k>Mw6C`-RkR#Ga(9KtIUpB=plvxj9jM zMqBI+8=6U-PTGrhyaVsb!{agN`gH0(1$q3N_%n;}m(+76{ICmvnK>CbK<|2ZyLcz! zkV6Lfx9>yyApUFcSv59F9lI4^6Yz9mx-lE~;aT`Fd;sCc3}vnXIhIqGj@ZQ6$miBU z=$$fVnbp=3@KgyOZ>=UlfLax)53=#;k+)RbBBN$n1s%^c_>Mvqi={$oV1Y z{-za_kIn{AkHN_Lj6>-IYB^#ne?v}lDD!>vUWF{ap$<=wKQo82DeDn<{SjLmP26Dk zI|f=Mq}jX#zi|LIgA5;{tV`NKi+qqbH&E7z9q?Vyo=5$^fmSJeyoWBPbjJsfw(sG_ z99M;&(PuTZ+SlVR#!`Rynp{LU@k@r_kJccoZ0gn=$hPPKK_lTazi1ZI(3!N(QS%fXwndjWtXI3HY5*$mN zYx~mv$ae^InmK=Z9{S%Ne#kR67rm2iN(6b0q;A;fB={c%5BDI%ci`b7?EdUQv{Pu; zQI8j?Zv(RJK>o)`mxioAK}MVQr)^NDuLsf|sL!1Z*yRk`BWbgsbt*QpD>6L`I={u9 z_RFV?a_GWu1Ls$vs~0HeX6*TKWOrU2ed7q~N&3#Kk%{1z?<0$N$^vl4(yU`|U z@xAaP-Ca)p+ec6yGW&P~{T;USFuM4x3|S(Jeq3wpw170H&ZKS~p+o#Q*7-9eN~+>BCmm%;bju$3K=$<6Tl0cExy zMmRD(5B_!?NSh_?Sgt!GmpyXn6S`o>v+oz{e?y*&GO!iuvW|MUZNuI+gk6pdJNLjZ z=dhLrK0DA3cA$=D_G1iD32&qu0KeZM|98;MyX#2L@vq2i6+9eSg}!MImqTM`2t0lYPDTe;(`HYn zuKj@8Y!)`~$==u_<&J`n)yQxJJmpc>yQur$u$^r58)?QK(nwFe-h{r!wO=B~o3Vvc zsq>@gd_KD08F>zXuTIGN4;=#CtzJ*tM`o|oU<2e|OxkSP@lbU2JY~Gp5xG%LIkxf; zJQY*7Tan?Bljz$i>x~HgY8P~|FYOOGJ&V3)AoHV1TY+tUIgByvF0={C{F%D^Js3zj-Eha~M8u4fYHl=Og11WPBBTJ(orQh7KyA zdo%pK3-5n}7un51=+9h09g){L;EomexcT@saBRRf z#x-J()6n^3>;l<;gdCn(hP`#d2O`fh^m8Tlqq^@xThce3j?P1V*x>f0t%HYK*J2mc z?XV@tk+vcm{0RPk>JEL%xQOzz3EP1Et|IxOLG<W-IHECp^5jFJ&JD zePr<+_V{fEV~vH#k+A8dl!0z{S&FZM&)1RDaCo_MZ}>y52Vj5CBcDO=IJKO62#d1FUVm~Tj)`z`>ESow7EU7lS|OwpWyvqZ~-!(0-wEC!yi1gqb}vO zjO9poDRC1C|1&ZkPP@w99-BoD7huQ3;PZ57zDM36=pi4TAEa$vkNz(rzCE&^)ioGH zmLk8qr{D{BB78gA0Xolwx4!Gp4LW#p9PP1ywzZ1#XfK0kliw3|dp6&-?SSp}AP=%A zqdn{m?|jVFWK-_@@b^46U5UM1KZ~^UqcA zPr3EIsRMLBgr~}R)O#W00P^2C!Jr&?rQF@IpLLY+BJ~?y#`p#qY(_>?;I#`f*q88| zD0>|B9SohDi;y*K>_%ks`9R7f|B#iGg+7N<_KO^!iPAUr$M%s`CiSbE%$NarRKw3* z)b9**dGcYBa zXVEV%CLgj}zlO2T9{9M`=oB8u!NWo5QumH&6Y)pn{WJ7O;1^yX{XEKejXHfWBIq-Y zL)Xh@(?=oCT}gZY82T6LSVZ1yhA<|?j@Oa?Ipozai9V9@_oAHc#Pz3)F4Qr%3w<&= zDYe|#QDk!(`9_j%Z+I-6MH%q82>I#9PusZWITrH!1=geJ0Hf}F-spCWkJ z2^!zPd+sFKGqOBrM|3}d{+O^4@cQ)-#z^GvI~LnO{$rqVEA)TDN0-6NhAxa(ko6GC z{yjD~Ad9wuUhW@8TSgA=WK%x*qPXv1M?b*#k-qBgnrA{ys)mUEt$>>hmtLC_v9Y48^XNBVKr@g#Sq(yM}Qaw4Q*+`_NPUC~T}Z zKCuUKY!~?R_n^7kc`@qGRmuNAj;2fqs#1T`4{RdA*HXmtmh>p*Nj6 zO~Y1l>KNCd->ciAi_zr82H!u7c}3{_lQb9fWUN#{8$oWT;d8#mhVF*WG;HJM&fM1` z%TsA@3#iNX$n0s#Is<+lE2qCk=WF4&|QsHSjllJI210@jZHhBjyn;LeXQFVeNd-IN%LH9=82GBaVK=r6&>u)eGK`! zBFDRs$raS$aq2em0PF%@M@+{5!Oyw-p)=Ay3O^^1{*iHv39;3$ORyK}QAhX#U9d;w z`Are^A^ix#ZkmV8kcrYC0^N?3`yy@nALP}2vTV5r`hA@Ali^GEQuYkR19!U3bFZ7cSzvSzNJobbCNoyE`AiEXFzyC3KV&kEbm~8KA9Mz?KWBIPjnVK8jSkdd&yXz<_#*rx^4&(*LC9gJRqzLn?tm}siLF8F1bAJ*^}FzXJv8Lg_N1=u zknKOQPwkhy0)F4XcWKO^@5y#WKd%yhEp$JLA}eTUPW$M=_-fL8ja;j+xADucNpyN7 z@#~Poh%)q0%6J>wI1E|VQtkxmHgq(yMQ2wa_bJ%QHA~@lI&vUvf5ILhUDHtNH4Qxv zpxvy87uwAb^s^Y7ykj5w7~1Ct$ayuoys8{u3D3_S4o}G9#6GlJ4!Xb&3m_i6(j>hlwr3ojZ+P1+lq%_ASSpG&$| z(RVpKoJqO+Bb#>ETW@$f9UVr-Fc!#$2hMM3#{S4t3C-e}v`fm`4IV#4{%>%8AM_iM z$!FB*JL=pH8N5nak7C( z2dm(}6gg7Q&B*I>`29EXnGU_j1|Sp4|A{s~27VU6R}XA_H)PXD9UmNpO(TQ3 z-O)dFoHP=DgZ>_b#u3!>LGs8SY@qCoq}jO)8Nyo?cA~z2I(G2bj@a(b*wI30QI}EF z|0no+C4!%a7JK%aS);M@J+MJ^^ABuVW3`3QJ|BK>Mo0Iy!H#J+yCcJsGVptp^9$+s zJpdbrrk<oVCX6 z9qb?*dCZ#1_=7x`=F)dix3iJ!_1MYV$ngjAE}%W=d7PeepG)2%cuJo|`f0Rf>T?~k znYtcZi*QZ8X`C-3PuCp!8tVBh^6L#RC%|J@WVQ=*uTI0R_vA>uE*wD`%Dn*E=dNSC zK>HX9Bk~zLA`OW7zk2M#7=dFsJUnvYJqt(8Kj7m> z@;{8+SYc}hqqC0*pFsM0!dG;pza2wcYsQ9GaNj|`baeDO^|}e!yxWB~jDD|+;>+g~ zj;!zR$@moBGWMkn!QWd`=mX1X)70Y}>i#j%v!8|N`(Knh5c|D``sKA@j6hrtwm1#l zXs^&Al>bQu^4^0!hqgZ(-M_>6JoIobw$U^U`B8_9sqgt?u^(hwJP1ETUfoO0hV~7_ zf3TLZKWY9z{+*F=Iy}{*lf8GtzTth+O6(5EW{*RTbp!GJlc)zY4_-!@(7Fd*974Um zMaGv?|N9Q79L{G@2R=e<8Ybd5W+Q84@XcZHjh&r`p58!C>nZ;__&vD;yimVSM-fjQ z9~y_>MbB3qLYt!8n+RJ;eZM0A$&@<|no}tIQh5Fh`E5e}b<};|gSpr0MjT}yf&6=u z_tL4oG`ha(~H8LZrsTcJ=2-{49RyB5Mb|Sn4eku1F>`u>f7nC6r>|ppV^d_F{5yF3Fw(~mZW?OuXRi~3>@ z(0-fxZk~Xi;pb!OQ#6#e-^dtaGGhYd@D+TUeXtwqu?D#pR?>c(@p0eFofvs>Wh zjP>++y|Dc{d^&nP7#R$soga^#YOTR*$e>#e?Ryn|ZwhvY{O^NiKV*LdyftALAE4t8 z;q`4~(f2^)SC5S!O7Yl!4YGfk{C`FEL*cCq`dul1#eUp>&Zl0T7^fn~P1O74-KaDA zJaaDnbX#l>Orc&K;bGiN?q%S$+jQJt>$f+7$PhN<>rJS#@fuG284fRV$pEscEBI9vc7}DgSTjX|W zIqjHwOvYX|PG)@r~%`q&@KE1JE0?iDn~v%4vsv?g}3rvC9*nxtVMAL$|@7eCagOJUbYF zNcl_2cP@H=m%5*{f;@(D$+tW8or~@+gO9`ZrA|YrH}yOSJM9C1|JohiM=)-I&R}Gu zb!gf7_#t?j0)Ib}{sHQJCN}Un@jD=&YpL5qrei|Cj2;h8VBE-kZCjJJw@3^!CRkF#wCQk1%~Z}d=AHVVi*09S6lczpFEm( zdz$)J48zW;_q+q~L*Qi6ehQy;^T@Lw<2vX~g~n^h{6g{!nn6F;gZ#)PmpIMypGE!+ zofr?n*L58jGeiQPu?zOHH+kM8&uHp3Ba?9Qj$T54jX)nm7v0f!59HVrecl7Vw~}`N z*Zn3iX0Ac*kBm+mkL=mw!en75uW$qK8}rLAZ3s%=s0ieQOofe{-_0?b<8!=A8mtAK zom*N~5Y5XiE-5Z#MQ7ps0>9ofVuHA7rG*8>`9=Ht@N^emR*+XwT3Eh+w4$`g$F*^B zr6nch`6YQ3vkHpKeOy}?mmJ>Ch36LM%_u1iz8jI@!U~G>O7aV$g=Nu-;)1fg+}Z4J zEx!3?kL5eRz{k5-w^p^ii=UlaJ|jA+?~Ob(q~ zSXn_SpZp2R@9e|!W)#fI4Z^nbVTJ6%?fB^8!tzUI9Smy7RZ(tmK6K6+xz@p zt}c`6+ttN|Ww3(_i%Etu$C!-nJ8&z3`CFTaHdQXMlFH4qMX|ItF(fC)%y+iHY+_;A z?4sQL^Gb@R6;6*L?&6}t;(};NX?{UzVexcyP&T_DuW(vnL4Is4@z(OpE-jf}T2NM2 zIHw@C#&~Oa3X9A2ZKXVladPCFAzR@so+nztN0~}tvM7IAVQE>+{?h*w8bu{@Q_(OR zf7u!%(@IM73ZfP8!-9!Y^wG}gBSIV9N@jhRW6SkKUlU^b$}2o|#OSnjryN(FhPua$ z`uh0wpX@yI_<_gWdF$p2f8U?5kwvw2%j}opN9vXBMl-Upp=zYQzf;p-zp`V}Nd<>S z6mTH+w>|$i0-Tiv2P2Q7pVol~ZEsuqFQAQVYyVsJ8Qa?b|C8;1E#rgvcOJjK}MJ;sn4H|STQV>V+Sj*sRr zmcj)*xrnh5c^4kbJuk;@=QHM{bGiR+=7G8~wtRzeA;*dMj*A!z4(yj^x-)*s&rdT; zICiT{GkqAJ_1u_d+A>zlJU`8T6DI5KG`nw5<{N27UPqoqM~?{Sy{h4rvbO!UNno1< zT9?2PMD+p4n+U;ce*L!FfG=ZQ>|=3S5zl`&R95+dy$m2$M z)$ffVfgc?W&#KSm(6|Cz39bTK-+MK<23!lS1J{Eaz>VN0a5K0C=pOSna68Z%!8^d6 z;4biYa5uOI+zajl_k(|c2f%~iA@DGG1pE^`3LXQGgD1d~;3@Dlcm`|&&w}T`^WX)b zbxtpVmw}!Kyb4|euY)(hn_x3|3%m{90q=tM!293>@FDmJd<;GTpMuZ8zrg1}_u>Br zUxKf|*WerQE%*+64}JhYf}g<8;1^(!ZyJbzbkGL01?@lv$OP>{2hb680-eEjpbN+X z+k>uP2ha_0i)VU(9YIg96WAH-0(ybopbzK^WTX8+e=q@YWmj0h(ve2K_*P zFaQh$yMjSrFc<=M14F^?U>Fz0kyZ1T(?Dpa{$Y#h?Vt2K#|hPzK6D1(*Zof_Y$nFdrNM4g?Fp zK_Chif=aLmRDo(x0~UiNU@52t2ZLo`IamSez)DaLR)Gf42%11MSPj;Ir|^?cgJ-}d z@GN)^JP%#~T2t^6cp1C`-UF|J*TEa$O|Tif1>|$z0q=rW!TaC?@FDmJd<;GTpMuYT z{QKuX&!7Gcz64(Zrhg3GfcX}D2fhbCfFHq6;Aij)Fz}xSA|M^K0c}A$kO4A5d(Z)N z1f4)a1KmLnup{URb^<$tUBHu+c_hc9z|r6s@LTXZa4h&eI1U^S zP5>u@lfcQ~58xE=M{p`Q4g3lG8JrHz0B3@;z}es&a4t9xoDcp2E&vyTi@?R;5^yQF z46Fs~z#-sJupS%+Hh{yyM(`VO1kjyw24FhQ-WfCeHgsDC_ib?3>T2we8n?}yjqS1w z?%vRK7p?dvF{$9-IJ91Sf%$!5_dW;E&)`a2og%_%k>ioB_@RXMwZ9 zIpADy9ylNT1zZ3w1Q&se!6o2Qa2dE9Tmh~GSAoBRtHCwkT5uh>9^3$K1UG@3!7boc za2vQC{0-az?gV#%zk|EMJ>Xt&AGja<13Um81P_6S!6V?G;8E}xcpN+do&-;Ur@=E| z6L=Op2c8EnfEU3_;AQX%con<`UI%Z0H^FA`7I+)H1KtJif%m}&;6v~c_!xWwJ_VnF ze}T`z7vSIEOYjx=8hiu31>b@1!4Kd^@DunM`~plGe;@+VK^xE(v;!F+6SM~%Ku6FC zbOzgjE+7kR54wUKKsUfvho%SE5%dH*ft|rFpcm*3`hdP58}tMH!2mE2>*0fVp5E*dNRX2Y>^?0&ozBf`y4s;3RM|_yafv{1KcAP6K}ee+H+6Gr*bPEO0hB z2b>Ge1LuRkfD6Ed;39A_xCC4ZE(4c?E5McDD)3iuHMj;`3$6p#gB!q&;3jZ0xCPt_ zZUeW2zkxfzo!~C;cW^hj2iyzp1NVb}fCs>X;34oZcm(_tJPIBIkAo+`pmgjM3<0}= zpNP72hiHVZNF_2*d~E(64)kzZ4%fffo&4lCV_1d V*d~E(64)kzZ4%fff&Y0D_+N`;Wd8sF literal 0 HcmV?d00001 diff --git a/bin/2.3/localizebugfix_2_3.7z b/bin/2.3/localizebugfix_2_3.7z new file mode 100644 index 0000000000000000000000000000000000000000..81726492075386069e0fc8f16b7f5d66ff41e0bd GIT binary patch literal 28950 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 B4SWCq literal 0 HcmV?d00001 diff --git a/bin/2.3/localizebugfix_mm_i386.so b/bin/2.3/localizebugfix_mm_i386.so new file mode 100644 index 0000000000000000000000000000000000000000..3acd4eca2acabe8dffaeeaf8d4e7c93245f1bc44 GIT binary patch literal 23268 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 XT}KA|p*RBx$)yXB=OM$0ZAkooW;8C~ literal 0 HcmV?d00001 diff --git a/include/CVector.h b/include/CVector.h new file mode 100644 index 0000000..1d733ab --- /dev/null +++ b/include/CVector.h @@ -0,0 +1,502 @@ +/* AMX Mod X +* +* by the AMX Mod X Development Team +* originally developed by OLO +* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +*/ + +#ifndef __CVECTOR_H__ +#define __CVECTOR_H__ + +#include + +// Vector +template class CVector +{ + bool Grow(size_t amount) + { + // automatic grow + size_t newSize = m_Size * 2; + + if (newSize == 0) + { + newSize = 8; + } + + while (m_CurrentUsedSize + amount > newSize) + { + newSize *= 2; + } + T *newData = new T[newSize]; + if (!newData) + return false; + if (m_Data) + { + for (size_t i=0; i= m_Size) + { + return Grow(amount); + } + else + { + return true; + } + } + + bool ChangeSize(size_t size) + { + // change size + if (size == m_Size) + return true; + + if (!size) + { + if (m_Data) + { + delete [] m_Data; + m_Data = NULL; + m_Size = 0; + } + return true; + } + + T *newData = new T[size]; + if (!newData) + return false; + if (m_Data) + { + size_t end = (m_CurrentUsedSize < size) ? (m_CurrentUsedSize) : size; + for (size_t i=0; i m_Size) + m_CurrentUsedSize = m_Size; + + return true; + } + + void FreeMemIfPossible() + { + if (!m_Data) + return; + + if (!m_CurrentUsedSize) + { + ChangeSize(0); + return; + } + + size_t newSize = m_Size; + while (m_CurrentUsedSize <= newSize / 2) + newSize /= 2; + + if (newSize != m_Size) + ChangeSize(newSize); + } +protected: + T *m_Data; + size_t m_Size; + size_t m_CurrentUsedSize; +public: + class iterator + { + protected: + T *m_Ptr; + public: + // constructors / destructors + iterator() + { + m_Ptr = NULL; + } + + iterator(T * ptr) + { + m_Ptr = ptr; + } + + // member functions + T * base() + { + return m_Ptr; + } + + const T * base() const + { + return m_Ptr; + } + + // operators + T & operator*() + { + return *m_Ptr; + } + + T * operator->() + { + return m_Ptr; + } + + iterator & operator++() // preincrement + { + ++m_Ptr; + return (*this); + } + + iterator operator++(int) // postincrement + { + iterator tmp = *this; + ++m_Ptr; + return tmp; + } + + iterator & operator--() // predecrement + { + --m_Ptr; + return (*this); + } + + iterator operator--(int) // postdecrememnt + { + iterator tmp = *this; + --m_Ptr; + return tmp; + } + + bool operator==(T * right) const + { + return (m_Ptr == right); + } + + bool operator==(const iterator & right) const + { + return (m_Ptr == right.m_Ptr); + } + + bool operator!=(T * right) const + { + return (m_Ptr != right); + } + + bool operator!=(const iterator & right) const + { + return (m_Ptr != right.m_Ptr); + } + + iterator & operator+=(size_t offset) + { + m_Ptr += offset; + return (*this); + } + + iterator & operator-=(size_t offset) + { + m_Ptr -= offset; + return (*this); + } + + iterator operator+(size_t offset) const + { + iterator tmp(*this); + tmp.m_Ptr += offset; + return tmp; + } + + iterator operator-(size_t offset) const + { + iterator tmp(*this); + tmp.m_Ptr -= offset; + return tmp; + } + + T & operator[](size_t offset) + { + return (*(*this + offset)); + } + + const T & operator[](size_t offset) const + { + return (*(*this + offset)); + } + + bool operator<(const iterator & right) const + { + return m_Ptr < right.m_Ptr; + } + + bool operator>(const iterator & right) const + { + return m_Ptr > right.m_Ptr; + } + + bool operator<=(const iterator & right) const + { + return m_Ptr <= right.m_Ptr; + } + + bool operator>=(const iterator & right) const + { + return m_Ptr >= right.m_Ptr; + } + + size_t operator-(const iterator & right) const + { + return m_Ptr - right.m_Ptr; + } + }; + + // constructors / destructors + CVector() + { + m_Size = 0; + m_CurrentUsedSize = 0; + m_Data = NULL; + } + + CVector(const CVector & other) + { + // copy data + m_Data = new T [other.m_CurrentUsedSize]; + m_Size = other.m_CurrentUsedSize; + m_CurrentUsedSize = other.m_CurrentUsedSize; + for (size_t i=0; i() + { + clear(); + } + + // interface + size_t size() const + { + return m_CurrentUsedSize; + } + + size_t capacity() const + { + return m_Size; + } + + iterator begin() const + { + return iterator(m_Data); + } + + iterator end() const + { + return iterator(m_Data + m_CurrentUsedSize); + } + + iterator iterAt(size_t pos) + { + if (pos > m_CurrentUsedSize) + assert(0); + return iterator(m_Data + pos); + } + + bool reserve(size_t newSize) + { + if (newSize > m_Size) + return ChangeSize(newSize); + return true; + } + + bool push_back(const T & elem) + { + if (!GrowIfNeeded(1)) + { + return false; + } + + m_Data[m_CurrentUsedSize++] = elem; + + return true; + } + + void pop_back() + { + --m_CurrentUsedSize; + if (m_CurrentUsedSize < 0) + m_CurrentUsedSize = 0; + + FreeMemIfPossible(); + } + + bool resize(size_t newSize) + { + if (!ChangeSize(newSize)) + return false; + m_CurrentUsedSize = newSize; + return true; + } + + bool empty() const + { + return (m_CurrentUsedSize == 0); + } + + T & at(size_t pos) + { + if (pos > m_CurrentUsedSize) + { + assert(0); + } + return m_Data[pos]; + } + + const T & at(size_t pos) const + { + if (pos > m_CurrentUsedSize) + { + assert(0); + } + return m_Data[pos]; + } + + T & operator[](size_t pos) + { + return at(pos); + } + + const T & operator[](size_t pos) const + { + return at(pos); + } + + T & front() + { + if (m_CurrentUsedSize < 1) + { + assert(0); + } + return m_Data[0]; + } + + const T & front() const + { + if (m_CurrentUsedSize < 1) + { + assert(0); + } + return m_Data[0]; + } + + T & back() + { + if (m_CurrentUsedSize < 1) + { + assert(0); + } + return m_Data[m_CurrentUsedSize - 1]; + } + + const T & back() const + { + if (m_CurrentUsedSize < 1) + { + assert(0); + } + return m_Data[m_CurrentUsedSize - 1]; + } + + iterator insert(iterator where, const T & value) + { + // validate iter + if (where < m_Data || where > (m_Data + m_CurrentUsedSize)) + return iterator(0); + + size_t ofs = where - begin(); + + if (!GrowIfNeeded(1)) + { + return false; + } + + ++m_CurrentUsedSize; + + where = begin() + ofs; + + // Move subsequent entries + for (T *ptr = m_Data + m_CurrentUsedSize - 2; ptr >= where.base(); --ptr) + *(ptr + 1) = *ptr; + + *where.base() = value; + + return where; + } + + iterator erase(iterator where) + { + // validate iter + if (where < m_Data || where >= (m_Data + m_CurrentUsedSize)) + return iterator(0); + + size_t ofs = where - begin(); + + if (m_CurrentUsedSize > 1) + { + // move + T *theend = m_Data + m_CurrentUsedSize; + for (T *ptr = where.base() + 1; ptr < theend; ++ptr) + *(ptr - 1) = *ptr; + } + + --m_CurrentUsedSize; + + FreeMemIfPossible(); + + return begin() + ofs; + } + + void clear() + { + m_Size = 0; + m_CurrentUsedSize = 0; + if (m_Data) + { + delete [] m_Data; + m_Data = NULL; + } + } +}; + +#endif // __CVECTOR_H__ + diff --git a/include/main.h b/include/main.h new file mode 100644 index 0000000..71d67a0 --- /dev/null +++ b/include/main.h @@ -0,0 +1,128 @@ +/* + * Localize Bug Fix + * Copyright (c) 2013 - 2014 AGHL.RU Dev Team + * + * http://aghl.ru/forum/ - Russian Half-Life and Adrenaline Gamer Community + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef _MAIN_H_ +#define _MAIN_H_ + +#include "memory.h" +#include "CVector.h" + +#include "extdll.h" +#include "meta_api.h" + +#define MAX_CLIENTS 32 + +#ifdef _WIN32 + #define SIZEOF_CLIENT_T 20504 + #define PLAYER_NAME_OFFSET 19720 +#else + #define SIZEOF_CLIENT_T 20212 + #define PLAYER_NAME_OFFSET 19432 +#endif + +typedef struct server_static_s +{ + int initialized; + int clients; + int maxclients; + //[..] +} server_static_t; + +const char *szLocalizeBuffer[] = +{ + "#GameUI_DetailTextures", + "#Team_Select","#Team_Select_Spect","#IG_Team_Select","#IG_Team_Select_Spect","#IG_VIP_Team_Select","#IG_VIP_Team_Select_Spect","#Terrorist_Select", + "#CT_Select","#Buy","#CT_BuyItem","#T_BuyItem","#DCT_BuyItem","#DT_BuyItem","#CT_BuyPistol","#T_BuyPistol","#AS_BuyShotgun","#BuyShotgun","#CT_BuySubMachineGun", + "#T_BuySubMachineGun","#AS_CT_BuySubMachineGun","#AS_T_BuySubMachineGun","#T_BuyRifle","#CT_BuyRifle","#AS_T_BuyRifle","#AS_CT_BuyRifle","#AS_T_BuyMachineGun", + "#BuyMachineGun","#RadioA","#RadioB","#RadioC","#AK47","#SG552","#M4A1","#Famas","#Galil","#Aug","#Scout","#ArcticWarfareMagnum","#G3SG1","#SG550","#USP45","#Glock18", + "#DesertEagle","#P228","#Beretta96G","#FiveSeven","#Super90","#XM1014","#mp5navy","#tmp","#FNP90","#Mac10","#UMP45","#M249","#Krieg552","#M4A1_Short","#Schmidt","#Magnum", + "#D3AU1","#Krieg550","#KM45Tactical","#Sidearm9X19mm","#NightHawk","#P228Compact","#Dual40","#ESFiveSeven","#Leone12","#AutoShotgun","#SubMachineGun","#SchmidtMP","#ESC90", + "#Mac10_Short","#KMUMP45","#ESM249","#TEAMS","#PLAYERS","#CLASS","#SCORE","#DEATHS","#LATENCY","#VOICE","#Menu_OK","#Menu_Cancel","#Menu_Spectate","#Team_AutoAssign", + "#Title_SelectYourTeam","#Target_Bombed","#VIP_Escaped","#VIP_Assassinated","#Terrorists_Escaped","#CTs_PreventEscape","#Escaping_Terrorists_Neutralized","#Bomb_Defused", + "#CTs_Win","#Terrorists_Win","#Round_Draw","#All_Hostages_Rescued","#Target_Saved","#Hostages_Not_Rescued","#Terrorists_Not_Escaped","#VIP_Not_Escaped","#Cannot_Buy_This", + "#Not_Enough_Money","#Weapon_Not_Available","#Already_Have_Kevlar","#Already_Have_Kevlar_Helmet","#Already_Have_Kevlar_Bought_Helmet","#Cannot_Carry_Anymore","#Already_Have_One", + "#Cannot_Switch_From_VIP","#All_Teams_Full","#Terrorists_Full","#CTs_Full","#Too_Many_Terrorists","#Too_Many_CTs","#Wait_3_Seconds","#Only_1_Team_Change","#Ignore_Broadcast_Messages", + "#Ignore_Broadcast_Team_Messages","#Accept_All_Messages","#Ignore_Radio","#Accept_Radio","#Command_Not_Available","#Defusing_Bomb_With_Defuse_Kit", + "#Defusing_Bomb_Without_Defuse_Kit","#Killed_Hostage","#Injured_Hostage","#Auto_Team_Balance_Next_Round","#All_VIP_Slots_Full","#Killed_Teammate", + "#Banned_For_Killing_Teammates","#Cannot_Vote_Map","#Weapon_Cannot_Be_Dropped","#Terrorist_Escaped","#C4_Plant_At_Bomb_Spot","#C4_Plant_Must_Be_On_Ground", + "#C4_Arming_Cancelled","#Bomb_Planted","#C4_Activated_At_Bomb_Spot","#Switch_To_BurstFire","#Switch_To_SemiAuto","#Switch_To_FullAuto","#TRAINING1","#TRAINING2","#TRAINING3", + "#TRAINING4","#TRAINING5","#TRAINING6","#TRAINING7","#GAMESAVED","#Game_Commencing","#Game_connected","#Game_disconnected","#Game_join_terrorist","#Game_join_ct", + "#Game_join_terrorist_auto","#Game_join_ct_auto","#Game_scoring","#Game_idle_kick","#Game_bomb_drop","#Game_bomb_pickup","#Game_no_timelimit","#Game_timelimit", + "#Game_unknown_command","#Game_in_position","#Game_added_position","#Game_teammate_kills","#Game_required_votes","#Game_radio","#Game_teammate_attack","#Game_kicked", + "#Game_vote_cast","#Game_vote_usage","#Game_vote_player_not_found","#Game_vote_players_on_your_team","#Game_vote_not_yourself","#Game_voted_for_map","#Game_votemap_usage", + "#Cannot_Vote_Need_More_People","#Map_Vote_Extend","#Cannot_Vote_With_Less_Than_Three","#Game_will_restart_in","#Game_will_restart_in_console","#Cover_me","#You_take_the_point", + "#Hold_this_position","#Regroup_team","#Follow_me","#Taking_fire","#Go_go_go","#Team_fall_back","#Stick_together_team","#Get_in_position_and_wait","#Storm_the_front","#Report_in_team", + "#Affirmative","#Roger_that","#Enemy_spotted","#Need_backup","#Sector_clear","#In_position","#Reporting_in","#Get_out_of_there","#Negative","#Enemy_down","#Hostage_down", + "#Fire_in_the_hole","#Cant_buy","#VIP_cant_buy","#CT_cant_buy","#Terrorist_cant_buy","#Vote","#Votes","#Hint_press_buy_to_purchase","#Hint_use_nightvision","#Hint_lost_money", + "#Hint_removed_for_next_hostage_killed","#Hint_careful_around_hostages","#Hint_careful_around_teammates","#Hint_reward_for_killing_vip","#Hint_win_round_by_killing_enemy", + "#Hint_try_not_to_injure_teammates","#Hint_you_are_in_targetzone","#Hint_hostage_rescue_zone","#Hint_terrorist_escape_zone","#Hint_ct_vip_zone","#Hint_terrorist_vip_zone", + "#Hint_cannot_play_because_tk","#Hint_use_hostage_to_stop_him","#Hint_lead_hostage_to_rescue_point","#Hint_you_have_the_bomb","#Hint_you_are_the_vip","#Hint_out_of_ammo", + "#Hint_spotted_a_friend","#Hint_spotted_an_enemy","#Hint_prevent_hostage_rescue","#Hint_rescue_the_hostages","#Hint_press_use_so_hostage_will_follow","#Friend","#Enemy","#Hostage", + "#Health","#Map_descr_not_avail","#Class_descr_not_avail","#Title_terrorist_model_selection","#Phoenix_Connexion","#L337_Krew","#Arctic_Avengers","#Guerilla_Warfare","#Auto_Select", + "#Title_ct_model_selection","#Seal_Team_6","#Title_seal_team","#GSG_9","#Title_gsg9","#SAS","#Title_sas","#GIGN","#Title_gign","#Title_select_category_of_purchase", + "#Title_equipment_selection","#Kevlar","#Kevlar_Vest","#Kevlar_Helmet","#Kevlar_Vest_Ballistic_Helmet","#Flashbang","#HE_Grenade","#High_Explosive_Grenade","#Smoke_Grenade", + "#Defusal_Kit","#Bomb_Defusal_Kit","#NightVision","#Nightvision_Goggles","#TactShield","#TactShield_Desc","#Title_pistol_selection","#Pistols","#Buy_pistols", + "#Title_shotgun_selection","#Shotguns","#Buy_shotguns","#Title_smg_selection","#SMGs","#Buy_smgs","#Title_rifle_selection","#Rifles","#Buy_rifles","#Title_machinegun_selection", + "#MachineGuns","#Buy_machineguns","#Prim_Ammo","#Buy_prim_ammo","#Sec_Ammo","#Buy_sec_ammo","#Equipment","#Buy_equipment","#Terrorist_Forces","#CT_Forces","#VIP","#WINS","#BOMB","#DEAD", + "#SCORES","#Player","#Player_plural","#Got_defuser","#Got_bomb","#Mic_Volume","#Speaker_Volume","#Voice_Properties","#Cannot_Be_Spectator","#Map_Description_not_available","#Muted", + "#Unmuted","#No_longer_hear_that_player","#OBS_NONE","#OBS_CHASE_LOCKED","#OBS_CHASE_FREE","#OBS_ROAMING","#OBS_IN_EYE","#OBS_MAP_FREE","#OBS_MAP_CHASE","#SPECT_OPTIONS","#CAM_OPTIONS", + "#Name_change_at_respawn","#C4_Defuse_Must_Be_On_Ground","#Spec_Mode1","#Spec_Mode2","#Spec_Mode3","#Spec_Mode4","#Spec_Mode5","#Spec_Mode6","#Spec_NoTarget","#Spec_Help_Title", + "#Spec_Help_Text","#Spec_Slow_Motion","#Spec_Replay","#Spec_Auto","#Spec_Time","#Spec_Map","#Spectators","#Unassigned","#Only_CT_Can_Move_Hostages","#Spec_Duck", + "#Spec_Not_Valid_Choice","#Spec_Not_In_Spectator_Mode","#Spec_NoPlayers","#Spec_ListPlayers","#Selection_Not_Available","#Alias_Not_Avail","#Spec_No_PIP" +}; + +extern DLL_FUNCTIONS *g_pFunctionTable; + +static server_static_t *global_svs; + +static CVector localize; + +static int localize_string(char *buf,bool apersand); + +static void (*pfnCmd_TokenizeString)(char *buf); + +static inline void localize_push() +{ + int j = (sizeof(szLocalizeBuffer) / sizeof(szLocalizeBuffer[0])); + + for(int i = 0; i < j; i++) + localize.push_back(szLocalizeBuffer[i]); +}; +static inline char *getClientName(edict_t *pEdict) +{ + unsigned int p = ENTINDEX(pEdict) - 1; + return (char *)(global_svs->clients + p * SIZEOF_CLIENT_T + PLAYER_NAME_OFFSET); +} + +#endif //_MAIN_H_ + diff --git a/include/memory.h b/include/memory.h new file mode 100644 index 0000000..095278a --- /dev/null +++ b/include/memory.h @@ -0,0 +1,85 @@ +/* + * Localize Bug Fix + * Copyright (c) 2013 - 2014 AGHL.RU Dev Team + * + * http://aghl.ru/forum/ - Russian Half-Life and Adrenaline Gamer Community + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef _MEMORY_H_ +#define _MEMORY_H_ + +#ifdef _WIN32 + #include + #include +#ifdef _MSC_VER <= 1600 + #define PSAPI_VERSION 1 +#endif +#else + #include + #include + #include + #include + #include + #include + #include + + #define Align(addr) ((void *)(((long)addr) & ~(sysconf(_SC_PAGESIZE) - 1))) +#endif + +#ifdef _MSC_VER + #pragma comment(lib,"psapi.lib") +#endif + +#ifndef dword + #define dword unsigned long +#endif + +struct lib_t +{ + char *base; + void *handle; + dword size; +}; + +int lib_load_info(void *addr,lib_t *lib); + +char *lib_find_pattern(lib_t *lib,const char *pattern,int len); +char *lib_find_pattern_fstr(lib_t *lib,const char *string,int range,const char *pattern,int len); + +char *mem_find_ref(char *start,int range,int opcode,dword ref,int relative); +char *mem_find_pattern(char *pos,int range,const char *pattern,int len); + +int mem_change_protection(void *addr,const char *patch,int len); + +#ifndef _WIN32 +char *lib_find_symbol(lib_t *lib,const char *symbol); +#endif + +#endif //_MEMORY_H_ + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..bd9c81e --- /dev/null +++ b/main.cpp @@ -0,0 +1,251 @@ +/* + * Localize Bug Fix + * Copyright (c) 2013 - 2014 AGHL.RU Dev Team + * + * http://aghl.ru/forum/ - Russian Half-Life and Adrenaline Gamer Community + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#include "main.h" + +void Cmd_TokenizeString_Handler(char *buf) +{ + if(!strncmp(buf,"say ",4) || !strncmp(buf,"say_team ",9)) + { + localize_string(buf,true); + } + pfnCmd_TokenizeString(buf); +} +void OnMetaAttach() +{ + lib_t lib; + + char *addr; + char patch[4]; + +#ifdef _WIN32 + char p1[] = "\x55\x8B\x2A\xA1\x2A\x2A\x2A\x2A\x56\x33\x2A\x85\x2A\x7E\x2A\x8B\x2A\x2A\x2A\x2A\x2A\x2A\x50"; + char p2[] = "\x56\xE8\x2A\x2A\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x50\xFF\x2A\x2A\x2A\x2A\x2A\x83\x2A\x2A\x5E\xC3"; +#endif + + lib_load_info((void *)gpGlobals,&lib); + +#ifdef _WIN32 + // * Cmd_TokenizeString | addr - 049A3FC0 + addr = lib_find_pattern(&lib,p1,sizeof(p1) - 1);//23 +#else + addr = lib_find_symbol(&lib,"Cmd_TokenizeString"); +#endif + if(!addr) + { + LOG_ERROR(PLID,"can't find \"Cmd_TokenizeString\""); + return; + } + + pfnCmd_TokenizeString = reinterpret_cast(addr); + +#ifdef _WIN32 + // * SV_ParseStringCommand | addr - 01DAB0AF + addr = lib_find_pattern(&lib,p2,sizeof(p2) - 1); + + if(!addr) + { + LOG_ERROR(PLID,"can't find \"Cmd_TokenizeString\" inside function \"SV_ParseStringCommand\""); + return; + } + // 01DAB0D8 56 push esi + // 01DAB0D9 E8 E2 8E F8 FF call Cmd_TokenizeString + + addr += 2;// 01DAB0D8 + 1 +#else + + addr = lib_find_symbol(&lib,"SV_ParseStringCommand"); + + if(!addr) + { + LOG_ERROR(PLID,"can't find \"SV_ParseStringCommand\""); + return; + } + + // 0009B1B0 53 push ebx + // 0009B1B1 E8 AA A5 FA FF call Cmd_TokenizeString + + addr = mem_find_ref(addr,200,'\xE8',(dword)pfnCmd_TokenizeString,1); + + if(!addr) + { + LOG_ERROR(PLID,"can't find \"Cmd_TokenizeString\" inside function \"SV_ParseStringCommand\""); + return; + } + + addr += 1; +#endif + *(dword *)patch = (dword)Cmd_TokenizeString_Handler - (dword)addr - 4; + + if(!mem_change_protection(addr,patch,sizeof(patch))) + { + LOG_ERROR(PLID,"patch failed."); + return; + } + +#ifdef _WIN32 + addr = lib_find_pattern_fstr(&lib,"# name userid uniqueid frag time ping loss adr\n",-12,"\x68\x2A\x2A\x2A\x2A\x53\x56",7); +#else + addr = lib_find_symbol(&lib,"svs"); +#endif + + if(!addr) + { + LOG_ERROR(PLID,"can't find \"svs\""); + return; + } + +#ifdef _WIN32 + addr += 25; + global_svs = (struct server_static_s *)(*(dword **)addr - 2); +#else + global_svs = (struct server_static_s *)addr; +#endif + + localize_push(); +}; +void ClientUserInfoChanged(edict_t *pEdict,char *infobuffer) +{ + if(!global_svs) + RETURN_META(MRES_IGNORED); + + char c; + char *s; + char *buf; + + int i = 0; + int j = 0; + + s = getClientName(pEdict); + buf = INFOKEY_VALUE(infobuffer,"name"); + + if(*s != '\0' && !strcmp(s,buf)) + RETURN_META(MRES_IGNORED); + + if(*s == '#') + *s = '*'; + + for(;*buf != '\0'; buf++, i++) + { + if(*buf != '+') + continue; + + c = *(buf + 1); + + if(!isspace(c) && (isdigit(c) || isalpha(c))) + { + *buf = '*'; + j++; + } + }; + + if(localize_string(buf -= i,false) || j) + { + SET_CLIENT_KEYVALUE(ENTINDEX(pEdict),infobuffer,"name",buf); + } + RETURN_META(MRES_IGNORED); +}; +#ifdef _WIN32 +static char *strcasestr(const char *phaystack,const char *pneedle) +{ + const char *a,*b; + for(;*phaystack; *phaystack++) + { + a = phaystack; + b = pneedle; + + while((*a++|32) == (*b++|32)) + { + if(!*b) + return (char *)phaystack; + } + } + return NULL; +}; +#endif +static int localize_string(char *buf,bool apersand) +{ + if(*buf == '\0') + { + return 0; + } + + int t = 0; + char *j,*a; + char *c = buf; + + if(apersand) + { + do { + if(*c == '%') + *c = ' '; + + t++; + + } while(*c++); + + c -= t; + } + + t = 0; + + while(1) + { + if(!c || !(j = strstr(c,"#"))) + break; + + c = j + 1; + + if(!isdigit(*c) && isalpha(*c) && !isspace(*c)) + { + CVector *p = &(localize); + for(CVector::iterator i = p->begin(); i != p->end(); i++) + { + while(1) + { + if(!(a = strcasestr(buf,(*i))) + && !(a = strcasestr(buf,"#CZero_")) + && !(a = strcasestr(buf,"#Cstrike_")) + && !(a = strcasestr(buf,"#Career_"))) + { + break; + } + + *a = '*'; + t++; + } + } + } + } + return (t > 0 && *buf != '\0'); +}; \ No newline at end of file diff --git a/memory.cpp b/memory.cpp new file mode 100644 index 0000000..d212f2c --- /dev/null +++ b/memory.cpp @@ -0,0 +1,194 @@ +/* + * Localize Bug Fix + * Copyright (c) 2013 - 2014 AGHL.RU Dev Team + * + * http://aghl.ru/forum/ - Russian Half-Life and Adrenaline Gamer Community + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#include "memory.h" + +#ifdef _WIN32 +int lib_load_info(void *addr,lib_t *lib) +{ + MEMORY_BASIC_INFORMATION mem; + VirtualQuery(addr,&mem,sizeof(mem)); + + IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER*)mem.AllocationBase; + IMAGE_NT_HEADERS *pe = (IMAGE_NT_HEADERS*)((dword)dos + (dword)dos->e_lfanew); + + if(pe->Signature != IMAGE_NT_SIGNATURE) + return 0; + + lib->base = (char *)mem.AllocationBase; + lib->size = (size_t)pe->OptionalHeader.SizeOfImage; + + return 1; +} +#else +char *lib_find_symbol(lib_t *lib,const char *symbol) +{ + return (char *)dlsym(lib->handle,symbol); +} +static ElfW(Addr) dlsize(void *base) +{ + int i; + ElfW(Ehdr) *ehdr; + ElfW(Phdr) *phdr; + ElfW(Addr) end; + + ehdr = (ElfW(Ehdr)*)base; + phdr = (ElfW(Phdr)*)((ElfW(Addr))ehdr + ehdr->e_phoff); + + for(i = 0; i < ehdr->e_phnum; ++i) + { + if(phdr[i].p_type == PT_LOAD) + end = phdr[i].p_vaddr + phdr[i].p_memsz; + } + return end; +} +int lib_load_info(void *addr,lib_t *lib) +{ + Dl_info info; + if(!dladdr(addr,&info) || !info.dli_fbase || !info.dli_fname) + return 0; + + lib->base = (char *)info.dli_fbase; + lib->size = dlsize(info.dli_fbase); + lib->handle = dlopen(info.dli_fname,RTLD_NOW); + + return 1; +} +#endif +static inline int mem_compare_c(const char *addr,const char *pattern,const char *pattern_end) +{ + const char *c; + for(c = pattern; c < pattern_end; ++c, ++addr) + { + if(*c == *addr || *c == '\x2A') + continue; + + return 0; + } + return 1; +} +static char *mem_find_ref_c(char *pos,char *end,int opcode,dword ref,int relative) +{ + for(; pos < end; ++pos) + { + if(*pos == opcode) + { + if(relative) + { + if((dword)pos + 5 + *(dword *)(pos + 1) == ref) + return pos; + } + else + { + if(*(dword *)(pos + 1) == ref) + return pos; + } + } + } + return NULL; +} +char *mem_find_pattern(char *pos,int range,const char *pattern,int len) +{ + char *end; + const char *pattern_end; + + pattern_end = pattern + len; + + for(end = pos + range - len; pos < end; ++pos) + { + if(mem_compare_c(pos,pattern,pattern_end)) + return pos; + } + return NULL; +} +static char *lib_find_string_push(lib_t *lib,const char *string) +{ + char *addr; + addr = mem_find_pattern(lib->base,lib->size,string,strlen(string) + 1); + return mem_find_ref_c(lib->base,lib->base + lib->size - 5,'\x68',(dword)addr,0); +} +char *mem_find_ref(char *start,int range,int opcode,dword ref,int relative) +{ + return mem_find_ref_c(start,start + range - 5,opcode,ref,relative); +} +char *lib_find_pattern(lib_t *lib,const char *pattern,int len) +{ + return mem_find_pattern(lib->base,lib->size,pattern,len); +} +char *lib_find_pattern_fstr(lib_t *lib,const char *string,int range,const char *pattern,int len) +{ + char *addr; + addr = lib_find_string_push(lib,string); + + if(addr) + { + if(range < 0) + { + addr += range; + range = -range; + } + return mem_find_pattern(addr,range,pattern,len); + } + return NULL; +} +int mem_change_protection(void *addr,const char *patch,int len) +{ +#ifdef _WIN32 + static HANDLE process = 0; + DWORD OldProtection,NewProtection = PAGE_EXECUTE_READWRITE; + + if(!process) + process = GetCurrentProcess(); + + FlushInstructionCache(process,addr,len); + if(VirtualProtect(addr,len,NewProtection,&OldProtection)) + { + memcpy(addr,patch,len); + return VirtualProtect(addr,len,OldProtection,&NewProtection); + } +#else + size_t size = sysconf(_SC_PAGESIZE); + void *alignedAddress = Align(addr); + + if(Align(addr + len - 1) != alignedAddress) + size *= 2; + + if(!mprotect(alignedAddress,size,(PROT_READ|PROT_WRITE|PROT_EXEC))) + { + memcpy(addr,patch,len); + return !mprotect(alignedAddress,size,(PROT_READ|PROT_EXEC)); + } +#endif + return 0; +} + diff --git a/meta_api.cpp b/meta_api.cpp new file mode 100644 index 0000000..6ef8582 --- /dev/null +++ b/meta_api.cpp @@ -0,0 +1,154 @@ +/* + * Localize Bug Fix + * Copyright (c) 2013 - 2014 AGHL.RU Dev Team + * + * http://aghl.ru/forum/ - Russian Half-Life and Adrenaline Gamer Community + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#include "extdll.h" +#include "meta_api.h" + +#undef C_DLLEXPORT + +#ifdef _WIN32 + #define C_DLLEXPORT extern "C" __declspec(dllexport) +#else + #include + #define C_DLLEXPORT extern "C" __attribute__((visibility("default"))) +#endif + +plugin_info_t Plugin_info = { + + META_INTERFACE_VERSION, + "LocalizeBug Fix", + "2.3", + "20/09/14", + "s1lent", + "http://www.aghl.ru/", + "LocalizeBug Fix", + PT_STARTUP, + PT_NEVER, +}; + +DLL_FUNCTIONS gpFunctionTable; +DLL_FUNCTIONS *g_pFunctionTable; +enginefuncs_t g_engfuncs; + +meta_globals_t *gpMetaGlobals; +gamedll_funcs_t *gpGamedllFuncs; +mutil_funcs_t *gpMetaUtilFuncs; + +globalvars_t *gpGlobals; +META_FUNCTIONS gMetaFunctionTable; + +void OnMetaAttach(); +void ClientCommand(edict_t *pEdict); +void ClientUserInfoChanged(edict_t *pEdict,char *infobuffer); + +C_DLLEXPORT int Meta_Query(char *,plugin_info_t **pPlugInfo,mutil_funcs_t *pMetaUtilFuncs) +{ + *pPlugInfo = &(Plugin_info); + gpMetaUtilFuncs = pMetaUtilFuncs; + return 1; +} +C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable,int *) +{ + memset(&gpFunctionTable,0,sizeof(DLL_FUNCTIONS)); + //gpFunctionTable.pfnClientCommand = ClientCommand; + gpFunctionTable.pfnClientUserInfoChanged = ClientUserInfoChanged; + memcpy(pFunctionTable,&gpFunctionTable,sizeof(DLL_FUNCTIONS)); + + g_pFunctionTable = pFunctionTable; + OnMetaAttach(); + + return 1; +} +C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now,META_FUNCTIONS *pFunctionTable,meta_globals_t *pMGlobals,gamedll_funcs_t *pGamedllFuncs) +{ + if(!pMGlobals || !pFunctionTable) + return 0; + + gpMetaGlobals = pMGlobals; + gpGamedllFuncs = pGamedllFuncs; + + gMetaFunctionTable.pfnGetEntityAPI2 = GetEntityAPI2; + memcpy(pFunctionTable,&gMetaFunctionTable,sizeof(META_FUNCTIONS)); + + return 1; +} +C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now,PL_UNLOAD_REASON reason) +{ + return 0; +} +#ifdef __linux__ + C_DLLEXPORT void GiveFnptrsToDll(enginefuncs_t *pengfuncsFromEngine,globalvars_t *pGlobals) { +#else + #ifdef _MSC_VER + C_DLLEXPORT __declspec(naked) void GiveFnptrsToDll(enginefuncs_t *pengfuncsFromEngine,globalvars_t *pGlobals) { + __asm { + push ebp + mov ebp,esp + sub esp,__LOCAL_SIZE + push ebx + push esi + push edi + } + #else // _MSC_VER + #ifdef __GNUC__ + C_DLLEXPORT void __stdcall GiveFnptrsToDll(enginefuncs_t *pengfuncsFromEngine,globalvars_t *pGlobals) { + #else + #error There is no support (yet) for your compiler. Please use MSVC or GCC compilers. + #endif + #endif // _MSC_VER +#endif // __linux__ + memcpy(&g_engfuncs,pengfuncsFromEngine,sizeof(enginefuncs_t)); + gpGlobals = pGlobals; + #ifdef _MSC_VER + if(sizeof(int *) == 8) { + __asm { + pop edi + pop esi + pop ebx + mov esp,ebp + pop ebp + ret 16 + } + } + else { + __asm { + pop edi + pop esi + pop ebx + mov esp,ebp + pop ebp + ret 8 + } + } + #endif // #ifdef _MSC_VER +} diff --git a/msvc10/localizebugfix.sln b/msvc10/localizebugfix.sln new file mode 100644 index 0000000..af09dbf --- /dev/null +++ b/msvc10/localizebugfix.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "localizebugfix", "localizebugfix.vcxproj", "{933B0D94-C6EC-47FB-AE34-2DC9F2B6D851}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {933B0D94-C6EC-47FB-AE34-2DC9F2B6D851}.Debug|Win32.ActiveCfg = Debug|Win32 + {933B0D94-C6EC-47FB-AE34-2DC9F2B6D851}.Debug|Win32.Build.0 = Debug|Win32 + {933B0D94-C6EC-47FB-AE34-2DC9F2B6D851}.Release|Win32.ActiveCfg = Release|Win32 + {933B0D94-C6EC-47FB-AE34-2DC9F2B6D851}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/msvc10/localizebugfix.suo b/msvc10/localizebugfix.suo new file mode 100644 index 0000000000000000000000000000000000000000..9eb70fbca80b30fa746f282edf0fd6039ae56eed GIT binary patch literal 13824 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 + + + + Debug + Win32 + + + Release + Win32 + + + + + + + + + + + + + + {933B0D94-C6EC-47FB-AE34-2DC9F2B6D851} + Win32Proj + shdetect + localizebugfix + + + + DynamicLibrary + true + v110 + MultiByte + + + DynamicLibrary + false + v100 + MultiByte + true + + + + + + + + + + + + + false + + + false + + + + + + TurnOffAllWarnings + Full + WIN32;NDEBUG;%(PreprocessorDefinitions) + include\;sdk\metamod;sdk\hlsdk\common;sdk\hlsdk\engine;sdk\hlsdk\dlls;sdk\hlsdk\pm_shared + Default + MultiThreadedDebugDLL + ProgramDatabase + + + Windows + false + false + false + %(AdditionalLibraryDirectories) + + + + + TurnOffAllWarnings + NotUsing + Full + true + false + WIN32;%(PreprocessorDefinitions) + ..\include\;..\sdk\metamod;..\sdk\hlsdk\common;..\sdk\hlsdk\engine;..\sdk\hlsdk\dlls;..\sdk\hlsdk\pm_shared + OnlyExplicitInline + false + false + MultiThreaded + + + + + + + Windows + true + true + true + psapi.lib + %(AdditionalLibraryDirectories) + + + false + + + + + + + echo "LocalizeBugFix Compiling" + + + + +copy /Y "$(TargetDir)localizebugfix.dll" "D:\HLDS\cstrike\addons\localizebugfix\localizebugfix.dll" + + + + + +copy /Y "$(TargetDir)localizebugfix.dll" "C:\CrashDumps\localizebugfix.dll" + + +copy /Y "$(TargetDir)localizebugfix.pdb" "C:\CrashDumps\localizebugfix.pdb" + + + + + +rmdir /q /s Release + + +IF EXIST "$(ProjectDir)ServerStart.bat" (CALL "$(ProjectDir)ServerStart.bat" "$(ProjectDir)..\" "$(ProjectDir)..\") + + + + + + \ No newline at end of file diff --git a/msvc10/localizebugfix.vcxproj.filters b/msvc10/localizebugfix.vcxproj.filters new file mode 100644 index 0000000..62a4779 --- /dev/null +++ b/msvc10/localizebugfix.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Файлы иÑходного кода + + + Файлы иÑходного кода + + + Файлы иÑходного кода + + + + + Заголовочные файлы + + + Заголовочные файлы + + + Заголовочные файлы + + + \ No newline at end of file diff --git a/sdk/hlsdk/common/beamdef.h b/sdk/hlsdk/common/beamdef.h new file mode 100644 index 0000000..e0d1096 --- /dev/null +++ b/sdk/hlsdk/common/beamdef.h @@ -0,0 +1,64 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined ( BEAMDEFH ) +#define BEAMDEFH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +#define FBEAM_STARTENTITY 0x00000001 +#define FBEAM_ENDENTITY 0x00000002 +#define FBEAM_FADEIN 0x00000004 +#define FBEAM_FADEOUT 0x00000008 +#define FBEAM_SINENOISE 0x00000010 +#define FBEAM_SOLID 0x00000020 +#define FBEAM_SHADEIN 0x00000040 +#define FBEAM_SHADEOUT 0x00000080 +#define FBEAM_STARTVISIBLE 0x10000000 // Has this client actually seen this beam's start entity yet? +#define FBEAM_ENDVISIBLE 0x20000000 // Has this client actually seen this beam's end entity yet? +#define FBEAM_ISACTIVE 0x40000000 +#define FBEAM_FOREVER 0x80000000 + +typedef struct beam_s BEAM; +struct beam_s +{ + BEAM *next; + int type; + int flags; + vec3_t source; + vec3_t target; + vec3_t delta; + float t; // 0 .. 1 over lifetime of beam + float freq; + float die; + float width; + float amplitude; + float r, g, b; + float brightness; + float speed; + float frameRate; + float frame; + int segments; + int startEntity; + int endEntity; + int modelIndex; + int frameCount; + struct model_s *pFollowModel; + struct particle_s *particles; +}; + +#endif diff --git a/sdk/hlsdk/common/cl_entity.h b/sdk/hlsdk/common/cl_entity.h new file mode 100644 index 0000000..0371a68 --- /dev/null +++ b/sdk/hlsdk/common/cl_entity.h @@ -0,0 +1,117 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// cl_entity.h +#if !defined( CL_ENTITYH ) +#define CL_ENTITYH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +typedef struct efrag_s +{ + struct mleaf_s *leaf; + struct efrag_s *leafnext; + struct cl_entity_s *entity; + struct efrag_s *entnext; +} efrag_t; + +typedef struct +{ + byte mouthopen; // 0 = mouth closed, 255 = mouth agape + byte sndcount; // counter for running average + int sndavg; // running average +} mouth_t; + +typedef struct +{ + float prevanimtime; + float sequencetime; + byte prevseqblending[2]; + vec3_t prevorigin; + vec3_t prevangles; + + int prevsequence; + float prevframe; + + byte prevcontroller[4]; + byte prevblending[2]; +} latchedvars_t; + +typedef struct +{ + // Time stamp for this movement + float animtime; + + vec3_t origin; + vec3_t angles; +} position_history_t; + +typedef struct cl_entity_s cl_entity_t; + +#define HISTORY_MAX 64 // Must be power of 2 +#define HISTORY_MASK ( HISTORY_MAX - 1 ) + + +#if !defined( ENTITY_STATEH ) +#include "entity_state.h" +#endif + +#if !defined( PROGS_H ) +#include "progs.h" +#endif + +struct cl_entity_s +{ + int index; // Index into cl_entities ( should match actual slot, but not necessarily ) + + qboolean player; // True if this entity is a "player" + + entity_state_t baseline; // The original state from which to delta during an uncompressed message + entity_state_t prevstate; // The state information from the penultimate message received from the server + entity_state_t curstate; // The state information from the last message received from server + + int current_position; // Last received history update index + position_history_t ph[ HISTORY_MAX ]; // History of position and angle updates for this player + + mouth_t mouth; // For synchronizing mouth movements. + + latchedvars_t latched; // Variables used by studio model rendering routines + + // Information based on interplocation, extrapolation, prediction, or just copied from last msg received. + // + float lastmove; + + // Actual render position and angles + vec3_t origin; + vec3_t angles; + + // Attachment points + vec3_t attachment[4]; + + // Other entity local information + int trivial_accept; + + struct model_s *model; // cl.model_precache[ curstate.modelindes ]; all visible entities have a model + struct efrag_s *efrag; // linked list of efrags + struct mnode_s *topnode; // for bmodels, first world node that splits bmodel, or NULL if not split + + float syncbase; // for client-side animations -- used by obsolete alias animation system, remove? + int visframe; // last frame this entity was found in an active leaf + colorVec cvFloorColor; +}; + +#endif // !CL_ENTITYH diff --git a/sdk/hlsdk/common/com_model.h b/sdk/hlsdk/common/com_model.h new file mode 100644 index 0000000..c87c980 --- /dev/null +++ b/sdk/hlsdk/common/com_model.h @@ -0,0 +1,353 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +// com_model.h +#if !defined( COM_MODEL_H ) +#define COM_MODEL_H +#if defined( _WIN32 ) +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +#define STUDIO_RENDER 1 +#define STUDIO_EVENTS 2 + +#define MAX_CLIENTS 32 +#define MAX_EDICTS 900 + +#define MAX_MODEL_NAME 64 +#define MAX_MAP_HULLS 4 +#define MIPLEVELS 4 +#define NUM_AMBIENTS 4 // automatic ambient sounds +#define MAXLIGHTMAPS 4 +#define PLANE_ANYZ 5 + +#define ALIAS_Z_CLIP_PLANE 5 + +// flags in finalvert_t.flags +#define ALIAS_LEFT_CLIP 0x0001 +#define ALIAS_TOP_CLIP 0x0002 +#define ALIAS_RIGHT_CLIP 0x0004 +#define ALIAS_BOTTOM_CLIP 0x0008 +#define ALIAS_Z_CLIP 0x0010 +#define ALIAS_ONSEAM 0x0020 +#define ALIAS_XY_CLIP_MASK 0x000F + +#define ZISCALE ((float)0x8000) + +#define CACHE_SIZE 32 // used to align key data structures + +typedef enum +{ + mod_brush, + mod_sprite, + mod_alias, + mod_studio +} modtype_t; + +// must match definition in modelgen.h +#ifndef SYNCTYPE_T +#define SYNCTYPE_T + +typedef enum +{ + ST_SYNC=0, + ST_RAND +} synctype_t; + +#endif + +typedef struct +{ + float mins[3], maxs[3]; + float origin[3]; + int headnode[MAX_MAP_HULLS]; + int visleafs; // not including the solid leaf 0 + int firstface, numfaces; +} dmodel_t; + +// plane_t structure +typedef struct mplane_s +{ + vec3_t normal; // surface normal + float dist; // closest appoach to origin + byte type; // for texture axis selection and fast side tests + byte signbits; // signx + signy<<1 + signz<<1 + byte pad[2]; +} mplane_t; + +typedef struct +{ + vec3_t position; +} mvertex_t; + +typedef struct +{ + unsigned short v[2]; + unsigned int cachededgeoffset; +} medge_t; + +typedef struct texture_s +{ + char name[16]; + unsigned width, height; + int anim_total; // total tenths in sequence ( 0 = no) + int anim_min, anim_max; // time for this frame min <=time< max + struct texture_s *anim_next; // in the animation sequence + struct texture_s *alternate_anims; // bmodels in frame 1 use these + unsigned offsets[MIPLEVELS]; // four mip maps stored + unsigned paloffset; +} texture_t; + +typedef struct +{ + float vecs[2][4]; // [s/t] unit vectors in world space. + // [i][3] is the s/t offset relative to the origin. + // s or t = dot(3Dpoint,vecs[i])+vecs[i][3] + float mipadjust; // ?? mipmap limits for very small surfaces + texture_t *texture; + int flags; // sky or slime, no lightmap or 256 subdivision +} mtexinfo_t; + +typedef struct mnode_s +{ +// common with leaf + int contents; // 0, to differentiate from leafs + int visframe; // node needs to be traversed if current + + short minmaxs[6]; // for bounding box culling + + struct mnode_s *parent; + +// node specific + mplane_t *plane; + struct mnode_s *children[2]; + + unsigned short firstsurface; + unsigned short numsurfaces; +} mnode_t; + +typedef struct msurface_s msurface_t; +typedef struct decal_s decal_t; + +// JAY: Compress this as much as possible +struct decal_s +{ + decal_t *pnext; // linked list for each surface + msurface_t *psurface; // Surface id for persistence / unlinking + short dx; // Offsets into surface texture (in texture coordinates, so we don't need floats) + short dy; + short texture; // Decal texture + byte scale; // Pixel scale + byte flags; // Decal flags + + short entityIndex; // Entity this is attached to +}; + +typedef struct mleaf_s +{ +// common with node + int contents; // wil be a negative contents number + int visframe; // node needs to be traversed if current + + short minmaxs[6]; // for bounding box culling + + struct mnode_s *parent; + +// leaf specific + byte *compressed_vis; + struct efrag_s *efrags; + + msurface_t **firstmarksurface; + int nummarksurfaces; + int key; // BSP sequence number for leaf's contents + byte ambient_sound_level[NUM_AMBIENTS]; +} mleaf_t; + +struct msurface_s +{ + int visframe; // should be drawn when node is crossed + + int dlightframe; // last frame the surface was checked by an animated light + int dlightbits; // dynamically generated. Indicates if the surface illumination + // is modified by an animated light. + + mplane_t *plane; // pointer to shared plane + int flags; // see SURF_ #defines + + int firstedge; // look up in model->surfedges[], negative numbers + int numedges; // are backwards edges + +// surface generation data + struct surfcache_s *cachespots[MIPLEVELS]; + + short texturemins[2]; // smallest s/t position on the surface. + short extents[2]; // ?? s/t texture size, 1..256 for all non-sky surfaces + + mtexinfo_t *texinfo; + +// lighting info + byte styles[MAXLIGHTMAPS]; // index into d_lightstylevalue[] for animated lights + // no one surface can be effected by more than 4 + // animated lights. + color24 *samples; + + decal_t *pdecals; +}; + +typedef struct +{ + int planenum; + short children[2]; // negative numbers are contents +} dclipnode_t; + +typedef struct hull_s +{ + dclipnode_t *clipnodes; + mplane_t *planes; + int firstclipnode; + int lastclipnode; + vec3_t clip_mins; + vec3_t clip_maxs; +} hull_t; + +#if !defined( CACHE_USER ) && !defined( QUAKEDEF_H ) +#define CACHE_USER +typedef struct cache_user_s +{ + void *data; +} cache_user_t; +#endif + +typedef struct model_s +{ + char name[ MAX_MODEL_NAME ]; + qboolean needload; // bmodels and sprites don't cache normally + + modtype_t type; + int numframes; + synctype_t synctype; + + int flags; + +// +// volume occupied by the model +// + vec3_t mins, maxs; + float radius; + +// +// brush model +// + int firstmodelsurface, nummodelsurfaces; + + int numsubmodels; + dmodel_t *submodels; + + int numplanes; + mplane_t *planes; + + int numleafs; // number of visible leafs, not counting 0 + struct mleaf_s *leafs; + + int numvertexes; + mvertex_t *vertexes; + + int numedges; + medge_t *edges; + + int numnodes; + mnode_t *nodes; + + int numtexinfo; + mtexinfo_t *texinfo; + + int numsurfaces; + msurface_t *surfaces; + + int numsurfedges; + int *surfedges; + + int numclipnodes; + dclipnode_t *clipnodes; + + int nummarksurfaces; + msurface_t **marksurfaces; + + hull_t hulls[MAX_MAP_HULLS]; + + int numtextures; + texture_t **textures; + + byte *visdata; + + color24 *lightdata; + + char *entities; + +// +// additional model data +// + cache_user_t cache; // only access through Mod_Extradata + +} model_t; + +typedef vec_t vec4_t[4]; + +typedef struct alight_s +{ + int ambientlight; // clip at 128 + int shadelight; // clip at 192 - ambientlight + vec3_t color; + float *plightvec; +} alight_t; + +typedef struct auxvert_s +{ + float fv[3]; // viewspace x, y +} auxvert_t; + +#include "custom.h" + +#define MAX_INFO_STRING 256 +#define MAX_SCOREBOARDNAME 32 +typedef struct player_info_s +{ + // User id on server + int userid; + + // User info string + char userinfo[ MAX_INFO_STRING ]; + + // Name + char name[ MAX_SCOREBOARDNAME ]; + + // Spectator or not, unused + int spectator; + + int ping; + int packet_loss; + + // skin information + char model[MAX_QPATH]; + int topcolor; + int bottomcolor; + + // last frame rendered + int renderframe; + + // Gait frame estimation + int gaitsequence; + float gaitframe; + float gaityaw; + vec3_t prevgaitorigin; + + customization_t customdata; +} player_info_t; + +#endif // #define COM_MODEL_H diff --git a/sdk/hlsdk/common/con_nprint.h b/sdk/hlsdk/common/con_nprint.h new file mode 100644 index 0000000..c563138 --- /dev/null +++ b/sdk/hlsdk/common/con_nprint.h @@ -0,0 +1,33 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined( CON_NPRINTH ) +#define CON_NPRINTH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +typedef struct con_nprint_s +{ + int index; // Row # + float time_to_live; // # of seconds before it dissappears + float color[ 3 ]; // RGB colors ( 0.0 -> 1.0 scale ) +} con_nprint_t; + +void Con_NPrintf( int idx, char *fmt, ... ); +void Con_NXPrintf( struct con_nprint_s *info, char *fmt, ... ); + +#endif diff --git a/sdk/hlsdk/common/const.h b/sdk/hlsdk/common/const.h new file mode 100644 index 0000000..c9b26a8 --- /dev/null +++ b/sdk/hlsdk/common/const.h @@ -0,0 +1,776 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef CONST_H +#define CONST_H +// +// Constants shared by the engine and dlls +// This header file included by engine files and DLL files. +// Most came from server.h + +// edict->flags +#define FL_FLY (1<<0) // Changes the SV_Movestep() behavior to not need to be on ground +#define FL_SWIM (1<<1) // Changes the SV_Movestep() behavior to not need to be on ground (but stay in water) +#define FL_CONVEYOR (1<<2) +#define FL_CLIENT (1<<3) +#define FL_INWATER (1<<4) +#define FL_MONSTER (1<<5) +#define FL_GODMODE (1<<6) +#define FL_NOTARGET (1<<7) +#define FL_SKIPLOCALHOST (1<<8) // Don't send entity to local host, it's predicting this entity itself +#define FL_ONGROUND (1<<9) // At rest / on the ground +#define FL_PARTIALGROUND (1<<10) // not all corners are valid +#define FL_WATERJUMP (1<<11) // player jumping out of water +#define FL_FROZEN (1<<12) // Player is frozen for 3rd person camera +#define FL_FAKECLIENT (1<<13) // JAC: fake client, simulated server side; don't send network messages to them +#define FL_DUCKING (1<<14) // Player flag -- Player is fully crouched +#define FL_FLOAT (1<<15) // Apply floating force to this entity when in water +#define FL_GRAPHED (1<<16) // worldgraph has this ent listed as something that blocks a connection + +// UNDONE: Do we need these? +#define FL_IMMUNE_WATER (1<<17) +#define FL_IMMUNE_SLIME (1<<18) +#define FL_IMMUNE_LAVA (1<<19) + +#define FL_PROXY (1<<20) // This is a spectator proxy +#define FL_ALWAYSTHINK (1<<21) // Brush model flag -- call think every frame regardless of nextthink - ltime (for constantly changing velocity/path) +#define FL_BASEVELOCITY (1<<22) // Base velocity has been applied this frame (used to convert base velocity into momentum) +#define FL_MONSTERCLIP (1<<23) // Only collide in with monsters who have FL_MONSTERCLIP set +#define FL_ONTRAIN (1<<24) // Player is _controlling_ a train, so movement commands should be ignored on client during prediction. +#define FL_WORLDBRUSH (1<<25) // Not moveable/removeable brush entity (really part of the world, but represented as an entity for transparency or something) +#define FL_SPECTATOR (1<<26) // This client is a spectator, don't run touch functions, etc. +#define FL_CUSTOMENTITY (1<<29) // This is a custom entity +#define FL_KILLME (1<<30) // This entity is marked for death -- This allows the engine to kill ents at the appropriate time +#define FL_DORMANT (1<<31) // Entity is dormant, no updates to client + + +// Goes into globalvars_t.trace_flags +#define FTRACE_SIMPLEBOX (1<<0) // Traceline with a simple box + + +// walkmove modes +#define WALKMOVE_NORMAL 0 // normal walkmove +#define WALKMOVE_WORLDONLY 1 // doesn't hit ANY entities, no matter what the solid type +#define WALKMOVE_CHECKONLY 2 // move, but don't touch triggers + +// edict->movetype values +#define MOVETYPE_NONE 0 // never moves +//#define MOVETYPE_ANGLENOCLIP 1 +//#define MOVETYPE_ANGLECLIP 2 +#define MOVETYPE_WALK 3 // Player only - moving on the ground +#define MOVETYPE_STEP 4 // gravity, special edge handling -- monsters use this +#define MOVETYPE_FLY 5 // No gravity, but still collides with stuff +#define MOVETYPE_TOSS 6 // gravity/collisions +#define MOVETYPE_PUSH 7 // no clip to world, push and crush +#define MOVETYPE_NOCLIP 8 // No gravity, no collisions, still do velocity/avelocity +#define MOVETYPE_FLYMISSILE 9 // extra size to monsters +#define MOVETYPE_BOUNCE 10 // Just like Toss, but reflect velocity when contacting surfaces +#define MOVETYPE_BOUNCEMISSILE 11 // bounce w/o gravity +#define MOVETYPE_FOLLOW 12 // track movement of aiment +#define MOVETYPE_PUSHSTEP 13 // BSP model that needs physics/world collisions (uses nearest hull for world collision) + +// edict->solid values +// NOTE: Some movetypes will cause collisions independent of SOLID_NOT/SOLID_TRIGGER when the entity moves +// SOLID only effects OTHER entities colliding with this one when they move - UGH! +#define SOLID_NOT 0 // no interaction with other objects +#define SOLID_TRIGGER 1 // touch on edge, but not blocking +#define SOLID_BBOX 2 // touch on edge, block +#define SOLID_SLIDEBOX 3 // touch on edge, but not an onground +#define SOLID_BSP 4 // bsp clip, touch on edge, block + +// edict->deadflag values +#define DEAD_NO 0 // alive +#define DEAD_DYING 1 // playing death animation or still falling off of a ledge waiting to hit ground +#define DEAD_DEAD 2 // dead. lying still. +#define DEAD_RESPAWNABLE 3 +#define DEAD_DISCARDBODY 4 + +#define DAMAGE_NO 0 +#define DAMAGE_YES 1 +#define DAMAGE_AIM 2 + +// entity effects +#define EF_BRIGHTFIELD 1 // swirling cloud of particles +#define EF_MUZZLEFLASH 2 // single frame ELIGHT on entity attachment 0 +#define EF_BRIGHTLIGHT 4 // DLIGHT centered at entity origin +#define EF_DIMLIGHT 8 // player flashlight +#define EF_INVLIGHT 16 // get lighting from ceiling +#define EF_NOINTERP 32 // don't interpolate the next frame +#define EF_LIGHT 64 // rocket flare glow sprite +#define EF_NODRAW 128 // don't draw entity + +// entity flags +#define EFLAG_SLERP 1 // do studio interpolation of this entity + +// +// temp entity events +// +#define TE_BEAMPOINTS 0 // beam effect between two points +// coord coord coord (start position) +// coord coord coord (end position) +// short (sprite index) +// byte (starting frame) +// byte (frame rate in 0.1's) +// byte (life in 0.1's) +// byte (line width in 0.1's) +// byte (noise amplitude in 0.01's) +// byte,byte,byte (color) +// byte (brightness) +// byte (scroll speed in 0.1's) + +#define TE_BEAMENTPOINT 1 // beam effect between point and entity +// short (start entity) +// coord coord coord (end position) +// short (sprite index) +// byte (starting frame) +// byte (frame rate in 0.1's) +// byte (life in 0.1's) +// byte (line width in 0.1's) +// byte (noise amplitude in 0.01's) +// byte,byte,byte (color) +// byte (brightness) +// byte (scroll speed in 0.1's) + +#define TE_GUNSHOT 2 // particle effect plus ricochet sound +// coord coord coord (position) + +#define TE_EXPLOSION 3 // additive sprite, 2 dynamic lights, flickering particles, explosion sound, move vertically 8 pps +// coord coord coord (position) +// short (sprite index) +// byte (scale in 0.1's) +// byte (framerate) +// byte (flags) +// +// The Explosion effect has some flags to control performance/aesthetic features: +#define TE_EXPLFLAG_NONE 0 // all flags clear makes default Half-Life explosion +#define TE_EXPLFLAG_NOADDITIVE 1 // sprite will be drawn opaque (ensure that the sprite you send is a non-additive sprite) +#define TE_EXPLFLAG_NODLIGHTS 2 // do not render dynamic lights +#define TE_EXPLFLAG_NOSOUND 4 // do not play client explosion sound +#define TE_EXPLFLAG_NOPARTICLES 8 // do not draw particles + + +#define TE_TAREXPLOSION 4 // Quake1 "tarbaby" explosion with sound +// coord coord coord (position) + +#define TE_SMOKE 5 // alphablend sprite, move vertically 30 pps +// coord coord coord (position) +// short (sprite index) +// byte (scale in 0.1's) +// byte (framerate) + +#define TE_TRACER 6 // tracer effect from point to point +// coord, coord, coord (start) +// coord, coord, coord (end) + +#define TE_LIGHTNING 7 // TE_BEAMPOINTS with simplified parameters +// coord, coord, coord (start) +// coord, coord, coord (end) +// byte (life in 0.1's) +// byte (width in 0.1's) +// byte (amplitude in 0.01's) +// short (sprite model index) + +#define TE_BEAMENTS 8 +// short (start entity) +// short (end entity) +// short (sprite index) +// byte (starting frame) +// byte (frame rate in 0.1's) +// byte (life in 0.1's) +// byte (line width in 0.1's) +// byte (noise amplitude in 0.01's) +// byte,byte,byte (color) +// byte (brightness) +// byte (scroll speed in 0.1's) + +#define TE_SPARKS 9 // 8 random tracers with gravity, ricochet sprite +// coord coord coord (position) + +#define TE_LAVASPLASH 10 // Quake1 lava splash +// coord coord coord (position) + +#define TE_TELEPORT 11 // Quake1 teleport splash +// coord coord coord (position) + +#define TE_EXPLOSION2 12 // Quake1 colormaped (base palette) particle explosion with sound +// coord coord coord (position) +// byte (starting color) +// byte (num colors) + +#define TE_BSPDECAL 13 // Decal from the .BSP file +// coord, coord, coord (x,y,z), decal position (center of texture in world) +// short (texture index of precached decal texture name) +// short (entity index) +// [optional - only included if previous short is non-zero (not the world)] short (index of model of above entity) + +#define TE_IMPLOSION 14 // tracers moving toward a point +// coord, coord, coord (position) +// byte (radius) +// byte (count) +// byte (life in 0.1's) + +#define TE_SPRITETRAIL 15 // line of moving glow sprites with gravity, fadeout, and collisions +// coord, coord, coord (start) +// coord, coord, coord (end) +// short (sprite index) +// byte (count) +// byte (life in 0.1's) +// byte (scale in 0.1's) +// byte (velocity along vector in 10's) +// byte (randomness of velocity in 10's) + +#define TE_BEAM 16 // obsolete + +#define TE_SPRITE 17 // additive sprite, plays 1 cycle +// coord, coord, coord (position) +// short (sprite index) +// byte (scale in 0.1's) +// byte (brightness) + +#define TE_BEAMSPRITE 18 // A beam with a sprite at the end +// coord, coord, coord (start position) +// coord, coord, coord (end position) +// short (beam sprite index) +// short (end sprite index) + +#define TE_BEAMTORUS 19 // screen aligned beam ring, expands to max radius over lifetime +// coord coord coord (center position) +// coord coord coord (axis and radius) +// short (sprite index) +// byte (starting frame) +// byte (frame rate in 0.1's) +// byte (life in 0.1's) +// byte (line width in 0.1's) +// byte (noise amplitude in 0.01's) +// byte,byte,byte (color) +// byte (brightness) +// byte (scroll speed in 0.1's) + +#define TE_BEAMDISK 20 // disk that expands to max radius over lifetime +// coord coord coord (center position) +// coord coord coord (axis and radius) +// short (sprite index) +// byte (starting frame) +// byte (frame rate in 0.1's) +// byte (life in 0.1's) +// byte (line width in 0.1's) +// byte (noise amplitude in 0.01's) +// byte,byte,byte (color) +// byte (brightness) +// byte (scroll speed in 0.1's) + +#define TE_BEAMCYLINDER 21 // cylinder that expands to max radius over lifetime +// coord coord coord (center position) +// coord coord coord (axis and radius) +// short (sprite index) +// byte (starting frame) +// byte (frame rate in 0.1's) +// byte (life in 0.1's) +// byte (line width in 0.1's) +// byte (noise amplitude in 0.01's) +// byte,byte,byte (color) +// byte (brightness) +// byte (scroll speed in 0.1's) + +#define TE_BEAMFOLLOW 22 // create a line of decaying beam segments until entity stops moving +// short (entity:attachment to follow) +// short (sprite index) +// byte (life in 0.1's) +// byte (line width in 0.1's) +// byte,byte,byte (color) +// byte (brightness) + +#define TE_GLOWSPRITE 23 +// coord, coord, coord (pos) short (model index) byte (scale / 10) + +#define TE_BEAMRING 24 // connect a beam ring to two entities +// short (start entity) +// short (end entity) +// short (sprite index) +// byte (starting frame) +// byte (frame rate in 0.1's) +// byte (life in 0.1's) +// byte (line width in 0.1's) +// byte (noise amplitude in 0.01's) +// byte,byte,byte (color) +// byte (brightness) +// byte (scroll speed in 0.1's) + +#define TE_STREAK_SPLASH 25 // oriented shower of tracers +// coord coord coord (start position) +// coord coord coord (direction vector) +// byte (color) +// short (count) +// short (base speed) +// short (ramdon velocity) + +#define TE_BEAMHOSE 26 // obsolete + +#define TE_DLIGHT 27 // dynamic light, effect world, minor entity effect +// coord, coord, coord (pos) +// byte (radius in 10's) +// byte byte byte (color) +// byte (brightness) +// byte (life in 10's) +// byte (decay rate in 10's) + +#define TE_ELIGHT 28 // point entity light, no world effect +// short (entity:attachment to follow) +// coord coord coord (initial position) +// coord (radius) +// byte byte byte (color) +// byte (life in 0.1's) +// coord (decay rate) + +#define TE_TEXTMESSAGE 29 +// short 1.2.13 x (-1 = center) +// short 1.2.13 y (-1 = center) +// byte Effect 0 = fade in/fade out + // 1 is flickery credits + // 2 is write out (training room) + +// 4 bytes r,g,b,a color1 (text color) +// 4 bytes r,g,b,a color2 (effect color) +// ushort 8.8 fadein time +// ushort 8.8 fadeout time +// ushort 8.8 hold time +// optional ushort 8.8 fxtime (time the highlight lags behing the leading text in effect 2) +// string text message (512 chars max sz string) +#define TE_LINE 30 +// coord, coord, coord startpos +// coord, coord, coord endpos +// short life in 0.1 s +// 3 bytes r, g, b + +#define TE_BOX 31 +// coord, coord, coord boxmins +// coord, coord, coord boxmaxs +// short life in 0.1 s +// 3 bytes r, g, b + +#define TE_KILLBEAM 99 // kill all beams attached to entity +// short (entity) + +#define TE_LARGEFUNNEL 100 +// coord coord coord (funnel position) +// short (sprite index) +// short (flags) + +#define TE_BLOODSTREAM 101 // particle spray +// coord coord coord (start position) +// coord coord coord (spray vector) +// byte (color) +// byte (speed) + +#define TE_SHOWLINE 102 // line of particles every 5 units, dies in 30 seconds +// coord coord coord (start position) +// coord coord coord (end position) + +#define TE_BLOOD 103 // particle spray +// coord coord coord (start position) +// coord coord coord (spray vector) +// byte (color) +// byte (speed) + +#define TE_DECAL 104 // Decal applied to a brush entity (not the world) +// coord, coord, coord (x,y,z), decal position (center of texture in world) +// byte (texture index of precached decal texture name) +// short (entity index) + +#define TE_FIZZ 105 // create alpha sprites inside of entity, float upwards +// short (entity) +// short (sprite index) +// byte (density) + +#define TE_MODEL 106 // create a moving model that bounces and makes a sound when it hits +// coord, coord, coord (position) +// coord, coord, coord (velocity) +// angle (initial yaw) +// short (model index) +// byte (bounce sound type) +// byte (life in 0.1's) + +#define TE_EXPLODEMODEL 107 // spherical shower of models, picks from set +// coord, coord, coord (origin) +// coord (velocity) +// short (model index) +// short (count) +// byte (life in 0.1's) + +#define TE_BREAKMODEL 108 // box of models or sprites +// coord, coord, coord (position) +// coord, coord, coord (size) +// coord, coord, coord (velocity) +// byte (random velocity in 10's) +// short (sprite or model index) +// byte (count) +// byte (life in 0.1 secs) +// byte (flags) + +#define TE_GUNSHOTDECAL 109 // decal and ricochet sound +// coord, coord, coord (position) +// short (entity index???) +// byte (decal???) + +#define TE_SPRITE_SPRAY 110 // spay of alpha sprites +// coord, coord, coord (position) +// coord, coord, coord (velocity) +// short (sprite index) +// byte (count) +// byte (speed) +// byte (noise) + +#define TE_ARMOR_RICOCHET 111 // quick spark sprite, client ricochet sound. +// coord, coord, coord (position) +// byte (scale in 0.1's) + +#define TE_PLAYERDECAL 112 // ??? +// byte (playerindex) +// coord, coord, coord (position) +// short (entity???) +// byte (decal number???) +// [optional] short (model index???) + +#define TE_BUBBLES 113 // create alpha sprites inside of box, float upwards +// coord, coord, coord (min start position) +// coord, coord, coord (max start position) +// coord (float height) +// short (model index) +// byte (count) +// coord (speed) + +#define TE_BUBBLETRAIL 114 // create alpha sprites along a line, float upwards +// coord, coord, coord (min start position) +// coord, coord, coord (max start position) +// coord (float height) +// short (model index) +// byte (count) +// coord (speed) + +#define TE_BLOODSPRITE 115 // spray of opaque sprite1's that fall, single sprite2 for 1..2 secs (this is a high-priority tent) +// coord, coord, coord (position) +// short (sprite1 index) +// short (sprite2 index) +// byte (color) +// byte (scale) + +#define TE_WORLDDECAL 116 // Decal applied to the world brush +// coord, coord, coord (x,y,z), decal position (center of texture in world) +// byte (texture index of precached decal texture name) + +#define TE_WORLDDECALHIGH 117 // Decal (with texture index > 256) applied to world brush +// coord, coord, coord (x,y,z), decal position (center of texture in world) +// byte (texture index of precached decal texture name - 256) + +#define TE_DECALHIGH 118 // Same as TE_DECAL, but the texture index was greater than 256 +// coord, coord, coord (x,y,z), decal position (center of texture in world) +// byte (texture index of precached decal texture name - 256) +// short (entity index) + +#define TE_PROJECTILE 119 // Makes a projectile (like a nail) (this is a high-priority tent) +// coord, coord, coord (position) +// coord, coord, coord (velocity) +// short (modelindex) +// byte (life) +// byte (owner) projectile won't collide with owner (if owner == 0, projectile will hit any client). + +#define TE_SPRAY 120 // Throws a shower of sprites or models +// coord, coord, coord (position) +// coord, coord, coord (direction) +// short (modelindex) +// byte (count) +// byte (speed) +// byte (noise) +// byte (rendermode) + +#define TE_PLAYERSPRITES 121 // sprites emit from a player's bounding box (ONLY use for players!) +// byte (playernum) +// short (sprite modelindex) +// byte (count) +// byte (variance) (0 = no variance in size) (10 = 10% variance in size) + +#define TE_PARTICLEBURST 122 // very similar to lavasplash. +// coord (origin) +// short (radius) +// byte (particle color) +// byte (duration * 10) (will be randomized a bit) + +#define TE_FIREFIELD 123 // makes a field of fire. +// coord (origin) +// short (radius) (fire is made in a square around origin. -radius, -radius to radius, radius) +// short (modelindex) +// byte (count) +// byte (flags) +// byte (duration (in seconds) * 10) (will be randomized a bit) +// +// to keep network traffic low, this message has associated flags that fit into a byte: +#define TEFIRE_FLAG_ALLFLOAT 1 // all sprites will drift upwards as they animate +#define TEFIRE_FLAG_SOMEFLOAT 2 // some of the sprites will drift upwards. (50% chance) +#define TEFIRE_FLAG_LOOP 4 // if set, sprite plays at 15 fps, otherwise plays at whatever rate stretches the animation over the sprite's duration. +#define TEFIRE_FLAG_ALPHA 8 // if set, sprite is rendered alpha blended at 50% else, opaque +#define TEFIRE_FLAG_PLANAR 16 // if set, all fire sprites have same initial Z instead of randomly filling a cube. + +#define TE_PLAYERATTACHMENT 124 // attaches a TENT to a player (this is a high-priority tent) +// byte (entity index of player) +// coord (vertical offset) ( attachment origin.z = player origin.z + vertical offset ) +// short (model index) +// short (life * 10 ); + +#define TE_KILLPLAYERATTACHMENTS 125 // will expire all TENTS attached to a player. +// byte (entity index of player) + +#define TE_MULTIGUNSHOT 126 // much more compact shotgun message +// This message is used to make a client approximate a 'spray' of gunfire. +// Any weapon that fires more than one bullet per frame and fires in a bit of a spread is +// a good candidate for MULTIGUNSHOT use. (shotguns) +// +// NOTE: This effect makes the client do traces for each bullet, these client traces ignore +// entities that have studio models.Traces are 4096 long. +// +// coord (origin) +// coord (origin) +// coord (origin) +// coord (direction) +// coord (direction) +// coord (direction) +// coord (x noise * 100) +// coord (y noise * 100) +// byte (count) +// byte (bullethole decal texture index) + +#define TE_USERTRACER 127 // larger message than the standard tracer, but allows some customization. +// coord (origin) +// coord (origin) +// coord (origin) +// coord (velocity) +// coord (velocity) +// coord (velocity) +// byte ( life * 10 ) +// byte ( color ) this is an index into an array of color vectors in the engine. (0 - ) +// byte ( length * 10 ) + + + +#define MSG_BROADCAST 0 // unreliable to all +#define MSG_ONE 1 // reliable to one (msg_entity) +#define MSG_ALL 2 // reliable to all +#define MSG_INIT 3 // write to the init string +#define MSG_PVS 4 // Ents in PVS of org +#define MSG_PAS 5 // Ents in PAS of org +#define MSG_PVS_R 6 // Reliable to PVS +#define MSG_PAS_R 7 // Reliable to PAS +#define MSG_ONE_UNRELIABLE 8 // Send to one client, but don't put in reliable stream, put in unreliable datagram ( could be dropped ) +#define MSG_SPEC 9 // Sends to all spectator proxies + +// contents of a spot in the world +#define CONTENTS_EMPTY -1 +#define CONTENTS_SOLID -2 +#define CONTENTS_WATER -3 +#define CONTENTS_SLIME -4 +#define CONTENTS_LAVA -5 +#define CONTENTS_SKY -6 +/* These additional contents constants are defined in bspfile.h +#define CONTENTS_ORIGIN -7 // removed at csg time +#define CONTENTS_CLIP -8 // changed to contents_solid +#define CONTENTS_CURRENT_0 -9 +#define CONTENTS_CURRENT_90 -10 +#define CONTENTS_CURRENT_180 -11 +#define CONTENTS_CURRENT_270 -12 +#define CONTENTS_CURRENT_UP -13 +#define CONTENTS_CURRENT_DOWN -14 + +#define CONTENTS_TRANSLUCENT -15 +*/ +#define CONTENTS_LADDER -16 + +#define CONTENT_FLYFIELD -17 +#define CONTENT_GRAVITY_FLYFIELD -18 +#define CONTENT_FOG -19 + +#define CONTENT_EMPTY -1 +#define CONTENT_SOLID -2 +#define CONTENT_WATER -3 +#define CONTENT_SLIME -4 +#define CONTENT_LAVA -5 +#define CONTENT_SKY -6 + +// channels +#define CHAN_AUTO 0 +#define CHAN_WEAPON 1 +#define CHAN_VOICE 2 +#define CHAN_ITEM 3 +#define CHAN_BODY 4 +#define CHAN_STREAM 5 // allocate stream channel from the static or dynamic area +#define CHAN_STATIC 6 // allocate channel from the static area +#define CHAN_NETWORKVOICE_BASE 7 // voice data coming across the network +#define CHAN_NETWORKVOICE_END 500 // network voice data reserves slots (CHAN_NETWORKVOICE_BASE through CHAN_NETWORKVOICE_END). + +// attenuation values +#define ATTN_NONE 0 +#define ATTN_NORM (float)0.8 +#define ATTN_IDLE (float)2 +#define ATTN_STATIC (float)1.25 + +// pitch values +#define PITCH_NORM 100 // non-pitch shifted +#define PITCH_LOW 95 // other values are possible - 0-255, where 255 is very high +#define PITCH_HIGH 120 + +// volume values +#define VOL_NORM 1.0 + +// plats +#define PLAT_LOW_TRIGGER 1 + +// Trains +#define SF_TRAIN_WAIT_RETRIGGER 1 +#define SF_TRAIN_START_ON 4 // Train is initially moving +#define SF_TRAIN_PASSABLE 8 // Train is not solid -- used to make water trains + +// buttons +#ifndef IN_BUTTONS_H +#include "in_buttons.h" +#endif + +// Break Model Defines + +#define BREAK_TYPEMASK 0x4F +#define BREAK_GLASS 0x01 +#define BREAK_METAL 0x02 +#define BREAK_FLESH 0x04 +#define BREAK_WOOD 0x08 + +#define BREAK_SMOKE 0x10 +#define BREAK_TRANS 0x20 +#define BREAK_CONCRETE 0x40 +#define BREAK_2 0x80 + +// Colliding temp entity sounds + +#define BOUNCE_GLASS BREAK_GLASS +#define BOUNCE_METAL BREAK_METAL +#define BOUNCE_FLESH BREAK_FLESH +#define BOUNCE_WOOD BREAK_WOOD +#define BOUNCE_SHRAP 0x10 +#define BOUNCE_SHELL 0x20 +#define BOUNCE_CONCRETE BREAK_CONCRETE +#define BOUNCE_SHOTSHELL 0x80 + +// Temp entity bounce sound types +#define TE_BOUNCE_NULL 0 +#define TE_BOUNCE_SHELL 1 +#define TE_BOUNCE_SHOTSHELL 2 + +// Rendering constants +enum +{ + kRenderNormal, // src + kRenderTransColor, // c*a+dest*(1-a) + kRenderTransTexture, // src*a+dest*(1-a) + kRenderGlow, // src*a+dest -- No Z buffer checks + kRenderTransAlpha, // src*srca+dest*(1-srca) + kRenderTransAdd, // src*a+dest +}; + +enum +{ + kRenderFxNone = 0, + kRenderFxPulseSlow, + kRenderFxPulseFast, + kRenderFxPulseSlowWide, + kRenderFxPulseFastWide, + kRenderFxFadeSlow, + kRenderFxFadeFast, + kRenderFxSolidSlow, + kRenderFxSolidFast, + kRenderFxStrobeSlow, + kRenderFxStrobeFast, + kRenderFxStrobeFaster, + kRenderFxFlickerSlow, + kRenderFxFlickerFast, + kRenderFxNoDissipation, + kRenderFxDistort, // Distort/scale/translate flicker + kRenderFxHologram, // kRenderFxDistort + distance fade + kRenderFxDeadPlayer, // kRenderAmt is the player index + kRenderFxExplode, // Scale up really big! + kRenderFxGlowShell, // Glowing Shell + kRenderFxClampMinScale, // Keep this sprite from getting very small (SPRITES only!) +}; + + +typedef int func_t; +typedef int string_t; + +typedef unsigned char byte; +typedef unsigned short word; +#define _DEF_BYTE_ + +#undef true +#undef false + +#ifndef __cplusplus +typedef enum {false, true} qboolean; +#else +typedef int qboolean; +#endif + +typedef struct +{ + byte r, g, b; +} color24; + +typedef struct +{ + unsigned r, g, b, a; +} colorVec; + +#ifdef _WIN32 +#pragma pack(push,2) +#endif + +typedef struct +{ + unsigned short r, g, b, a; +} PackedColorVec; + +#ifdef _WIN32 +#pragma pack(pop) +#endif +typedef struct link_s +{ + struct link_s *prev, *next; +} link_t; + +typedef struct edict_s edict_t; + +typedef struct +{ + vec3_t normal; + float dist; +} plane_t; + +typedef struct +{ + qboolean allsolid; // if true, plane is not valid + qboolean startsolid; // if true, the initial point was in a solid area + qboolean inopen, inwater; + float fraction; // time completed, 1.0 = didn't hit anything + vec3_t endpos; // final position + plane_t plane; // surface normal at impact + edict_t *ent; // entity the surface is on + int hitgroup; // 0 == generic, non zero is specific body part +} trace_t; + +#endif + diff --git a/sdk/hlsdk/common/crc.h b/sdk/hlsdk/common/crc.h new file mode 100644 index 0000000..55cb234 --- /dev/null +++ b/sdk/hlsdk/common/crc.h @@ -0,0 +1,54 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +/* crc.h */ +#ifndef CRC_H +#define CRC_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +// MD5 Hash +typedef struct +{ + unsigned int buf[4]; + unsigned int bits[2]; + unsigned char in[64]; +} MD5Context_t; + + +typedef unsigned long CRC32_t; +void CRC32_Init(CRC32_t *pulCRC); +CRC32_t CRC32_Final(CRC32_t pulCRC); +void CRC32_ProcessBuffer(CRC32_t *pulCRC, void *p, int len); +void CRC32_ProcessByte(CRC32_t *pulCRC, unsigned char ch); +int CRC_File(CRC32_t *crcvalue, char *pszFileName); + +unsigned char COM_BlockSequenceCRCByte (unsigned char *base, int length, int sequence); + +void MD5Init(MD5Context_t *context); +void MD5Update(MD5Context_t *context, unsigned char const *buf, + unsigned int len); +void MD5Final(unsigned char digest[16], MD5Context_t *context); +void Transform(unsigned int buf[4], unsigned int const in[16]); + +int MD5_Hash_File(unsigned char digest[16], char *pszFileName, int bUsefopen, int bSeed, unsigned int seed[4]); +char *MD5_Print(unsigned char hash[16]); +int MD5_Hash_CachedFile(unsigned char digest[16], unsigned char *pCache, int nFileSize, int bSeed, unsigned int seed[4]); + +int CRC_MapFile(CRC32_t *crcvalue, char *pszFileName); + +#endif diff --git a/sdk/hlsdk/common/cvardef.h b/sdk/hlsdk/common/cvardef.h new file mode 100644 index 0000000..8390134 --- /dev/null +++ b/sdk/hlsdk/common/cvardef.h @@ -0,0 +1,36 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef CVARDEF_H +#define CVARDEF_H + +#define FCVAR_ARCHIVE (1<<0) // set to cause it to be saved to vars.rc +#define FCVAR_USERINFO (1<<1) // changes the client's info string +#define FCVAR_SERVER (1<<2) // notifies players when changed +#define FCVAR_EXTDLL (1<<3) // defined by external DLL +#define FCVAR_CLIENTDLL (1<<4) // defined by the client dll +#define FCVAR_PROTECTED (1<<5) // It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value +#define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server. +#define FCVAR_PRINTABLEONLY (1<<7) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ). +#define FCVAR_UNLOGGED (1<<8) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log + +typedef struct cvar_s +{ + char *name; + char *string; + int flags; + float value; + struct cvar_s *next; +} cvar_t; +#endif diff --git a/sdk/hlsdk/common/demo_api.h b/sdk/hlsdk/common/demo_api.h new file mode 100644 index 0000000..0130679 --- /dev/null +++ b/sdk/hlsdk/common/demo_api.h @@ -0,0 +1,33 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined ( DEMO_APIH ) +#define DEMO_APIH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +typedef struct demo_api_s +{ + int ( *IsRecording ) ( void ); + int ( *IsPlayingback ) ( void ); + int ( *IsTimeDemo ) ( void ); + void ( *WriteBuffer ) ( int size, unsigned char *buffer ); +} demo_api_t; + +extern demo_api_t demoapi; + +#endif diff --git a/sdk/hlsdk/common/director_cmds.h b/sdk/hlsdk/common/director_cmds.h new file mode 100644 index 0000000..4c8fdd5 --- /dev/null +++ b/sdk/hlsdk/common/director_cmds.h @@ -0,0 +1,38 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +// director_cmds.h +// sub commands for svc_director + +#define DRC_ACTIVE 0 // tells client that he's an spectator and will get director command +#define DRC_STATUS 1 // send status infos about proxy +#define DRC_CAMERA 2 // set the actual director camera position +#define DRC_EVENT 3 // informs the dircetor about ann important game event + + +#define DRC_FLAG_PRIO_MASK 0x0F // priorities between 0 and 15 (15 most important) +#define DRC_FLAG_SIDE (1<<4) +#define DRC_FLAG_DRAMATIC (1<<5) + + + +// commands of the director API function CallDirectorProc(...) + +#define DRCAPI_NOP 0 // no operation +#define DRCAPI_ACTIVE 1 // de/acivates director mode in engine +#define DRCAPI_STATUS 2 // request proxy information +#define DRCAPI_SETCAM 3 // set camera n to given position and angle +#define DRCAPI_GETCAM 4 // request camera n position and angle +#define DRCAPI_DIRPLAY 5 // set director time and play with normal speed +#define DRCAPI_DIRFREEZE 6 // freeze directo at this time +#define DRCAPI_SETVIEWMODE 7 // overview or 4 cameras +#define DRCAPI_SETOVERVIEWPARAMS 8 // sets parameter for overview mode +#define DRCAPI_SETFOCUS 9 // set the camera which has the input focus +#define DRCAPI_GETTARGETS 10 // queries engine for player list +#define DRCAPI_SETVIEWPOINTS 11 // gives engine all waypoints + + diff --git a/sdk/hlsdk/common/dlight.h b/sdk/hlsdk/common/dlight.h new file mode 100644 index 0000000..6a4f5b3 --- /dev/null +++ b/sdk/hlsdk/common/dlight.h @@ -0,0 +1,35 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined ( DLIGHTH ) +#define DLIGHTH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +typedef struct dlight_s +{ + vec3_t origin; + float radius; + color24 color; + float die; // stop lighting after this time + float decay; // drop this each second + float minlight; // don't add when contributing less + int key; + qboolean dark; // subtracts light instead of adding +} dlight_t; + +#endif diff --git a/sdk/hlsdk/common/dll_state.h b/sdk/hlsdk/common/dll_state.h new file mode 100644 index 0000000..4065162 --- /dev/null +++ b/sdk/hlsdk/common/dll_state.h @@ -0,0 +1,23 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +//DLL State Flags + +#define DLL_INACTIVE 0 // no dll +#define DLL_ACTIVE 1 // dll is running +#define DLL_PAUSED 2 // dll is paused +#define DLL_CLOSE 3 // closing down dll +#define DLL_TRANS 4 // Level Transition + +// DLL Pause reasons + +#define DLL_NORMAL 0 // User hit Esc or something. +#define DLL_QUIT 4 // Quit now +#define DLL_RESTART 6 // Switch to launcher for linux, does a quit but returns 1 + +// DLL Substate info ( not relevant ) +#define ENG_NORMAL (1<<0) diff --git a/sdk/hlsdk/common/engine_launcher_api.h b/sdk/hlsdk/common/engine_launcher_api.h new file mode 100644 index 0000000..c669856 --- /dev/null +++ b/sdk/hlsdk/common/engine_launcher_api.h @@ -0,0 +1,112 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +// engine/launcher interface +#if !defined( ENGINE_LAUNCHER_APIH ) +#define ENGINE_LAUNCHER_APIH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +//typedef void ( *xcommand_t ) ( void ); + +#define RENDERTYPE_UNDEFINED 0 +#define RENDERTYPE_SOFTWARE 1 +#define RENDERTYPE_HARDWARE 2 + +#define ENGINE_LAUNCHER_API_VERSION 1 + +typedef struct engine_api_s +{ + int version; + int rendertype; + int size; + + // Functions + int ( *GetEngineState ) ( void ); + void ( *Cbuf_AddText ) ( char *text ); // append cmd at end of buf + void ( *Cbuf_InsertText ) ( char *text ); // insert cmd at start of buf + void ( *Cmd_AddCommand ) ( char *cmd_name, void ( *funcname )( void ) ); + int ( *Cmd_Argc ) ( void ); + char *( *Cmd_Args ) ( void ); + char *( *Cmd_Argv ) ( int arg ); + void ( *Con_Printf ) ( char *, ... ); + void ( *Con_SafePrintf ) ( char *, ... ); + void ( *Cvar_Set ) ( char *var_name, char *value ); + void ( *Cvar_SetValue ) ( char *var_name, float value ); + int ( *Cvar_VariableInt ) ( char *var_name ); + char *( *Cvar_VariableString ) ( char *var_name ); + float ( *Cvar_VariableValue ) ( char *var_name ); + void ( *ForceReloadProfile ) ( void ); + int ( *GetGameInfo ) ( struct GameInfo_s *pGI, char *pszChannel ); + void ( *GameSetBackground ) ( int bBack ); + void ( *GameSetState ) ( int iState ); + void ( *GameSetSubState ) ( int iState ); + int ( *GetPauseState ) ( void ); + int ( *Host_Frame ) ( float time, int iState, int *stateInfo ); + void ( *Host_GetHostInfo ) ( float *fps, int *nActive, int *nSpectators, int *nMaxPlayers, char *pszMap ); + void ( *Host_Shutdown ) ( void ); + int ( *Game_Init ) ( char *lpCmdLine, unsigned char *pMem, int iSize, struct exefuncs_s *pef, void *, int ); + void ( *IN_ActivateMouse ) ( void ); + void ( *IN_ClearStates ) ( void ); + void ( *IN_DeactivateMouse ) ( void ); + void ( *IN_MouseEvent ) ( int mstate ); + void ( *Keyboard_ReturnToGame ) ( void ); + void ( *Key_ClearStates ) ( void ); + void ( *Key_Event ) ( int key, int down ); + int ( *LoadGame ) ( const char *pszSlot ); + void ( *S_BlockSound ) ( void ); + void ( *S_ClearBuffer ) ( void ); + void ( *S_GetDSPointer ) ( struct IDirectSound **lpDS, struct IDirectSoundBuffer **lpDSBuf ); + void *( *S_GetWAVPointer ) ( void ); + void ( *S_UnblockSound ) ( void ); + int ( *SaveGame ) ( const char *pszSlot, const char *pszComment ); + void ( *SetAuth ) ( void *pobj ); + void ( *SetMessagePumpDisableMode ) ( int bMode ); + void ( *SetPauseState ) ( int bPause ); + void ( *SetStartupMode ) ( int bMode ); + void ( *SNDDMA_Shutdown ) ( void ); + void ( *Snd_AcquireBuffer ) ( void ); + void ( *Snd_ReleaseBuffer ) ( void ); + void ( *StoreProfile ) ( void ); + double ( *Sys_FloatTime ) ( void ); + void ( *VID_UpdateWindowVars ) ( void *prc, int x, int y ); + void ( *VID_UpdateVID ) ( struct viddef_s *pvid ); + + // VGUI interfaces + void ( *VGui_CallEngineSurfaceProc ) ( void* hwnd, unsigned int msg, unsigned int wparam, long lparam ); + + // notifications that the launcher is taking/giving focus to the engine + void ( *EngineTakingFocus ) ( void ); + void ( *LauncherTakingFocus ) ( void ); + +#ifdef _WIN32 + // Only filled in by rendertype RENDERTYPE_HARDWARE + void ( *GL_Init ) ( void ); + int ( *GL_SetMode ) ( HWND hwndGame, HDC *pmaindc, HGLRC *pbaseRC, int fD3D, const char *p, const char *pszCmdLine ); + void ( *GL_Shutdown ) ( HWND hwnd, HDC hdc, HGLRC hglrc ); + + void ( *QGL_D3DShared ) ( struct tagD3DGlobals *d3dGShared ); + + int ( WINAPI *glSwapBuffers ) ( HDC dc ); + void ( *DirectorProc ) ( unsigned int cmd, void * params ); +#else + // NOT USED IN LINUX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + void ( *GL_Init ) ( void ); + void ( *GL_SetMode ) ( void ); + void ( *GL_Shutdown ) ( void ); + void ( *QGL_D3DShared ) ( void ); + void ( *glSwapBuffers ) ( void ); + void ( *DirectorProc ) ( void ); + // LINUX +#endif + +} engine_api_t; + +#endif // ENGINE_LAUNCHER_APIH diff --git a/sdk/hlsdk/common/entity_state.h b/sdk/hlsdk/common/entity_state.h new file mode 100644 index 0000000..fe4c097 --- /dev/null +++ b/sdk/hlsdk/common/entity_state.h @@ -0,0 +1,195 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined( ENTITY_STATEH ) +#define ENTITY_STATEH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +// For entityType below +#define ENTITY_NORMAL (1<<0) +#define ENTITY_BEAM (1<<1) + +// Entity state is used for the baseline and for delta compression of a packet of +// entities that is sent to a client. +typedef struct entity_state_s entity_state_t; + +struct entity_state_s +{ +// Fields which are filled in by routines outside of delta compression + int entityType; + // Index into cl_entities array for this entity. + int number; + float msg_time; + + // Message number last time the player/entity state was updated. + int messagenum; + + // Fields which can be transitted and reconstructed over the network stream + vec3_t origin; + vec3_t angles; + + int modelindex; + int sequence; + float frame; + int colormap; + short skin; + short solid; + int effects; + float scale; + + byte eflags; + + // Render information + int rendermode; + int renderamt; + color24 rendercolor; + int renderfx; + + int movetype; + float animtime; + float framerate; + int body; + byte controller[4]; + byte blending[4]; + vec3_t velocity; + + // Send bbox down to client for use during prediction. + vec3_t mins; + vec3_t maxs; + + int aiment; + // If owned by a player, the index of that player ( for projectiles ). + int owner; + + // Friction, for prediction. + float friction; + // Gravity multiplier + float gravity; + +// PLAYER SPECIFIC + int team; + int playerclass; + int health; + qboolean spectator; + int weaponmodel; + int gaitsequence; + // If standing on conveyor, e.g. + vec3_t basevelocity; + // Use the crouched hull, or the regular player hull. + int usehull; + // Latched buttons last time state updated. + int oldbuttons; + // -1 = in air, else pmove entity number + int onground; + int iStepLeft; + // How fast we are falling + float flFallVelocity; + + float fov; + int weaponanim; + + // Parametric movement overrides + vec3_t startpos; + vec3_t endpos; + float impacttime; + float starttime; + + // For mods + int iuser1; + int iuser2; + int iuser3; + int iuser4; + float fuser1; + float fuser2; + float fuser3; + float fuser4; + vec3_t vuser1; + vec3_t vuser2; + vec3_t vuser3; + vec3_t vuser4; +}; + +#include "pm_info.h" + +typedef struct clientdata_s +{ + vec3_t origin; + vec3_t velocity; + + int viewmodel; + vec3_t punchangle; + int flags; + int waterlevel; + int watertype; + vec3_t view_ofs; + float health; + + int bInDuck; + + int weapons; // remove? + + int flTimeStepSound; + int flDuckTime; + int flSwimTime; + int waterjumptime; + + float maxspeed; + + float fov; + int weaponanim; + + int m_iId; + int ammo_shells; + int ammo_nails; + int ammo_cells; + int ammo_rockets; + float m_flNextAttack; + + int tfstate; + + int pushmsec; + + int deadflag; + + char physinfo[ MAX_PHYSINFO_STRING ]; + + // For mods + int iuser1; + int iuser2; + int iuser3; + int iuser4; + float fuser1; + float fuser2; + float fuser3; + float fuser4; + vec3_t vuser1; + vec3_t vuser2; + vec3_t vuser3; + vec3_t vuser4; +} clientdata_t; + +#include "weaponinfo.h" + +typedef struct local_state_s +{ + entity_state_t playerstate; + clientdata_t client; + weapon_data_t weapondata[ 32 ]; +} local_state_t; + +#endif // !ENTITY_STATEH diff --git a/sdk/hlsdk/common/entity_types.h b/sdk/hlsdk/common/entity_types.h new file mode 100644 index 0000000..ff783df --- /dev/null +++ b/sdk/hlsdk/common/entity_types.h @@ -0,0 +1,26 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// entity_types.h +#if !defined( ENTITY_TYPESH ) +#define ENTITY_TYPESH + +#define ET_NORMAL 0 +#define ET_PLAYER 1 +#define ET_TEMPENTITY 2 +#define ET_BEAM 3 +// BMODEL or SPRITE that was split across BSP nodes +#define ET_FRAGMENTED 4 + +#endif // !ENTITY_TYPESH diff --git a/sdk/hlsdk/common/event_api.h b/sdk/hlsdk/common/event_api.h new file mode 100644 index 0000000..c49c25d --- /dev/null +++ b/sdk/hlsdk/common/event_api.h @@ -0,0 +1,53 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined ( EVENT_APIH ) +#define EVENT_APIH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +#define EVENT_API_VERSION 1 + +typedef struct event_api_s +{ + int version; + void ( *EV_PlaySound ) ( int ent, float *origin, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch ); + void ( *EV_StopSound ) ( int ent, int channel, const char *sample ); + int ( *EV_FindModelIndex )( const char *pmodel ); + int ( *EV_IsLocal ) ( int playernum ); + int ( *EV_LocalPlayerDucking ) ( void ); + void ( *EV_LocalPlayerViewheight ) ( float * ); + void ( *EV_LocalPlayerBounds ) ( int hull, float *mins, float *maxs ); + int ( *EV_IndexFromTrace) ( struct pmtrace_s *pTrace ); + struct physent_s *( *EV_GetPhysent ) ( int idx ); + void ( *EV_SetUpPlayerPrediction ) ( int dopred, int bIncludeLocalClient ); + void ( *EV_PushPMStates ) ( void ); + void ( *EV_PopPMStates ) ( void ); + void ( *EV_SetSolidPlayers ) (int playernum); + void ( *EV_SetTraceHull ) ( int hull ); + void ( *EV_PlayerTrace ) ( float *start, float *end, int traceFlags, int ignore_pe, struct pmtrace_s *tr ); + void ( *EV_WeaponAnimation ) ( int sequence, int body ); + unsigned short ( *EV_PrecacheEvent ) ( int type, const char* psz ); + void ( *EV_PlaybackEvent ) ( int flags, const struct edict_s *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); + const char *( *EV_TraceTexture ) ( int ground, float *vstart, float *vend ); + void ( *EV_StopAllSounds ) ( int entnum, int entchannel ); + void ( *EV_KillEvents ) ( int entnum, const char *eventname ); +} event_api_t; + +extern event_api_t eventapi; + +#endif diff --git a/sdk/hlsdk/common/event_args.h b/sdk/hlsdk/common/event_args.h new file mode 100644 index 0000000..7d7d9b3 --- /dev/null +++ b/sdk/hlsdk/common/event_args.h @@ -0,0 +1,52 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined( EVENT_ARGSH ) +#define EVENT_ARGSH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +// Event was invoked with stated origin +#define FEVENT_ORIGIN ( 1<<0 ) + +// Event was invoked with stated angles +#define FEVENT_ANGLES ( 1<<1 ) + +typedef struct event_args_s +{ + int flags; + + // Transmitted + int entindex; + + float origin[3]; + float angles[3]; + float velocity[3]; + + int ducking; + + float fparam1; + float fparam2; + + int iparam1; + int iparam2; + + int bparam1; + int bparam2; +} event_args_t; + +#endif diff --git a/sdk/hlsdk/common/event_flags.h b/sdk/hlsdk/common/event_flags.h new file mode 100644 index 0000000..fb19ae3 --- /dev/null +++ b/sdk/hlsdk/common/event_flags.h @@ -0,0 +1,49 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined( EVENT_FLAGSH ) +#define EVENT_FLAGSH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +// Skip local host for event send. +#define FEV_NOTHOST (1<<0) + +// Send the event reliably. You must specify the origin and angles and use +// PLAYBACK_EVENT_FULL for this to work correctly on the server for anything +// that depends on the event origin/angles. I.e., the origin/angles are not +// taken from the invoking edict for reliable events. +#define FEV_RELIABLE (1<<1) + +// Don't restrict to PAS/PVS, send this event to _everybody_ on the server ( useful for stopping CHAN_STATIC +// sounds started by client event when client is not in PVS anymore ( hwguy in TFC e.g. ). +#define FEV_GLOBAL (1<<2) + +// If this client already has one of these events in its queue, just update the event instead of sending it as a duplicate +// +#define FEV_UPDATE (1<<3) + +// Only send to entity specified as the invoker +#define FEV_HOSTONLY (1<<4) + +// Only send if the event was created on the server. +#define FEV_SERVER (1<<5) + +// Only issue event client side ( from shared code ) +#define FEV_CLIENT (1<<6) + +#endif diff --git a/sdk/hlsdk/common/exefuncs.h b/sdk/hlsdk/common/exefuncs.h new file mode 100644 index 0000000..cf07310 --- /dev/null +++ b/sdk/hlsdk/common/exefuncs.h @@ -0,0 +1,50 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +// exefuncs.h +#ifndef EXEFUNCS_H +#define EXEFUNCS_H + +// Engine hands this to DLLs for functionality callbacks +typedef struct exefuncs_s +{ + int fMMX; + int iCPUMhz; + void (*unused1)(void); + void (*unused2)(void); + void (*unused3)(void); + void (*unused4)(void); + void (*VID_ForceLockState)(int lk); + int (*VID_ForceUnlockedAndReturnState)(void); + void (*unused5)(void); + void (*unused6)(void); + void (*unused7)(void); + void (*unused8)(void); + void (*unused9)(void); + void (*unused10)(void); + void (*unused11)(void); + void (*unused12)(void); + void (*unused13)(void); + void (*unused14)(void); + void (*unused15)(void); + void (*ErrorMessage)(int nLevel, const char *pszErrorMessage); + void (*unused16)(void); + void (*Sys_Printf)(char *fmt, ...); + void (*unused17)(void); + void (*unused18)(void); + void (*unused19)(void); + void (*unused20)(void); + void (*unused21)(void); + void (*unused22)(void); + void (*unused23)(void); + void (*unused24)(void); + void (*unused25)(void); + void (*unused26)(void); + void (*unused27)(void); +} exefuncs_t; + +#endif diff --git a/sdk/hlsdk/common/hltv.h b/sdk/hlsdk/common/hltv.h new file mode 100644 index 0000000..4099b7e --- /dev/null +++ b/sdk/hlsdk/common/hltv.h @@ -0,0 +1,57 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +// hltv.h +// all shared consts between server, clients and proxy + +#ifndef HLTV_H +#define HLTV_H + +#define TYPE_CLIENT 0 // client is a normal HL client (default) +#define TYPE_PROXY 1 // client is another proxy +#define TYPE_COMMENTATOR 3 // client is a commentator +#define TYPE_DEMO 4 // client is a demo file +// sub commands of svc_hltv: +#define HLTV_ACTIVE 0 // tells client that he's an spectator and will get director commands +#define HLTV_STATUS 1 // send status infos about proxy +#define HLTV_LISTEN 2 // tell client to listen to a multicast stream + +// sub commands of svc_director: +#define DRC_CMD_NONE 0 // NULL director command +#define DRC_CMD_START 1 // start director mode +#define DRC_CMD_EVENT 2 // informs about director command +#define DRC_CMD_MODE 3 // switches camera modes +#define DRC_CMD_CAMERA 4 // sets camera registers +#define DRC_CMD_TIMESCALE 5 // sets time scale +#define DRC_CMD_MESSAGE 6 // send HUD centerprint +#define DRC_CMD_SOUND 7 // plays a particular sound +#define DRC_CMD_STATUS 8 // status info about broadcast +#define DRC_CMD_BANNER 9 // banner file name for HLTV gui +#define DRC_CMD_FADE 10 // send screen fade command +#define DRC_CMD_SHAKE 11 // send screen shake command +#define DRC_CMD_STUFFTEXT 12 // like the normal svc_stufftext but as director command + +#define DRC_CMD_LAST 12 + + + +// HLTV_EVENT event flags +#define DRC_FLAG_PRIO_MASK 0x0F // priorities between 0 and 15 (15 most important) +#define DRC_FLAG_SIDE (1<<4) // +#define DRC_FLAG_DRAMATIC (1<<5) // is a dramatic scene +#define DRC_FLAG_SLOWMOTION (1<<6) // would look good in SloMo +#define DRC_FLAG_FACEPLAYER (1<<7) // player is doning something (reload/defuse bomb etc) +#define DRC_FLAG_INTRO (1<<8) // is a introduction scene +#define DRC_FLAG_FINAL (1<<9) // is a final scene +#define DRC_FLAG_NO_RANDOM (1<<10) // don't randomize event data + + +#define MAX_DIRECTOR_CMD_PARAMETERS 4 +#define MAX_DIRECTOR_CMD_STRING 128 + + +#endif // HLTV_H diff --git a/sdk/hlsdk/common/in_buttons.h b/sdk/hlsdk/common/in_buttons.h new file mode 100644 index 0000000..77294ad --- /dev/null +++ b/sdk/hlsdk/common/in_buttons.h @@ -0,0 +1,40 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef IN_BUTTONS_H +#define IN_BUTTONS_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +#define IN_ATTACK (1 << 0) +#define IN_JUMP (1 << 1) +#define IN_DUCK (1 << 2) +#define IN_FORWARD (1 << 3) +#define IN_BACK (1 << 4) +#define IN_USE (1 << 5) +#define IN_CANCEL (1 << 6) +#define IN_LEFT (1 << 7) +#define IN_RIGHT (1 << 8) +#define IN_MOVELEFT (1 << 9) +#define IN_MOVERIGHT (1 << 10) +#define IN_ATTACK2 (1 << 11) +#define IN_RUN (1 << 12) +#define IN_RELOAD (1 << 13) +#define IN_ALT1 (1 << 14) +#define IN_SCORE (1 << 15) // Used by client.dll for when scoreboard is held down + +#endif // IN_BUTTONS_H diff --git a/sdk/hlsdk/common/interface.h b/sdk/hlsdk/common/interface.h new file mode 100644 index 0000000..b49d087 --- /dev/null +++ b/sdk/hlsdk/common/interface.h @@ -0,0 +1,129 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +// This header defines the interface convention used in the valve engine. +// To make an interface and expose it: +// 1. Derive from IBaseInterface. +// 2. The interface must be ALL pure virtuals, and have no data members. +// 3. Define a name for it. +// 4. In its implementation file, use EXPOSE_INTERFACE or EXPOSE_SINGLE_INTERFACE. + +// Versioning +// There are two versioning cases that are handled by this: +// 1. You add functions to the end of an interface, so it is binary compatible with the previous interface. In this case, +// you need two EXPOSE_INTERFACEs: one to expose your class as the old interface and one to expose it as the new interface. +// 2. You update an interface so it's not compatible anymore (but you still want to be able to expose the old interface +// for legacy code). In this case, you need to make a new version name for your new interface, and make a wrapper interface and +// expose it for the old interface. + +#ifndef INTERFACE_H +#define INTERFACE_H + +#ifdef __cplusplus + +// All interfaces derive from this. +class IBaseInterface +{ +public: + + virtual ~IBaseInterface() {} +}; + + +#define CREATEINTERFACE_PROCNAME "CreateInterface" +typedef IBaseInterface* (*CreateInterfaceFn)(const char *pName, int *pReturnCode); + + +typedef IBaseInterface* (*InstantiateInterfaceFn)(); + + +// Used internally to register classes. +class InterfaceReg +{ +public: + InterfaceReg(InstantiateInterfaceFn fn, const char *pName); + +public: + + InstantiateInterfaceFn m_CreateFn; + const char *m_pName; + + InterfaceReg *m_pNext; // For the global list. + static InterfaceReg *s_pInterfaceRegs; +}; + + +// Use this to expose an interface that can have multiple instances. +// e.g.: +// EXPOSE_INTERFACE( CInterfaceImp, IInterface, "MyInterface001" ) +// This will expose a class called CInterfaceImp that implements IInterface (a pure class) +// clients can receive a pointer to this class by calling CreateInterface( "MyInterface001" ) +// +// In practice, the shared header file defines the interface (IInterface) and version name ("MyInterface001") +// so that each component can use these names/vtables to communicate +// +// A single class can support multiple interfaces through multiple inheritance +// +#define EXPOSE_INTERFACE_FN(functionName, interfaceName, versionName) \ + static InterfaceReg __g_Create##className##_reg(functionName, versionName); + +#define EXPOSE_INTERFACE(className, interfaceName, versionName) \ + static IBaseInterface* __Create##className##_interface() {return (interfaceName *)new className;}\ + static InterfaceReg __g_Create##className##_reg(__Create##className##_interface, versionName ); + +// Use this to expose a singleton interface with a global variable you've created. +#define EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, globalVarName) \ + static IBaseInterface* __Create##className##interfaceName##_interface() {return (interfaceName *)&globalVarName;}\ + static InterfaceReg __g_Create##className##interfaceName##_reg(__Create##className##interfaceName##_interface, versionName); + +// Use this to expose a singleton interface. This creates the global variable for you automatically. +#define EXPOSE_SINGLE_INTERFACE(className, interfaceName, versionName) \ + static className __g_##className##_singleton;\ + EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, __g_##className##_singleton) + + +#ifdef WIN32 + #define EXPORT_FUNCTION __declspec(dllexport) +#else + #define EXPORT_FUNCTION +#endif + + +// This function is automatically exported and allows you to access any interfaces exposed with the above macros. +// if pReturnCode is set, it will return one of the following values +// extend this for other error conditions/code +enum +{ + IFACE_OK = 0, + IFACE_FAILED +}; + + +extern "C" +{ + EXPORT_FUNCTION IBaseInterface* CreateInterface(const char *pName, int *pReturnCode); +}; + + +// Handle to an interface (HInterfaceModule_t* is just there for type safety). +typedef struct HInterfaceModule_t* HINTERFACEMODULE; + + +// Use these to load and unload a module. +extern HINTERFACEMODULE Sys_LoadModule(const char *pModuleName); +extern void Sys_FreeModule(HINTERFACEMODULE hModule); + +// Use these to get the factory function from either a loaded module or the current module. +extern CreateInterfaceFn Sys_GetFactory( HINTERFACEMODULE hModule ); +extern CreateInterfaceFn Sys_GetFactoryThis( void ); + +#endif // __cplusplus + +#endif + + + diff --git a/sdk/hlsdk/common/ivoicetweak.h b/sdk/hlsdk/common/ivoicetweak.h new file mode 100644 index 0000000..c5f3402 --- /dev/null +++ b/sdk/hlsdk/common/ivoicetweak.h @@ -0,0 +1,37 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef IVOICETWEAK_H +#define IVOICETWEAK_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +// These provide access to the voice controls. +typedef enum +{ + MicrophoneVolume=0, // values 0-1. + OtherSpeakerScale // values 0-1. Scales how loud other players are. +} VoiceTweakControl; + + +typedef struct IVoiceTweak_s +{ + // These turn voice tweak mode on and off. While in voice tweak mode, the user's voice is echoed back + // without sending to the server. + int (*StartVoiceTweakMode)(); // Returns 0 on error. + void (*EndVoiceTweakMode)(); + + // Get/set control values. + void (*SetControlFloat)(VoiceTweakControl iControl, float value); + float (*GetControlFloat)(VoiceTweakControl iControl); +} IVoiceTweak; + + +#endif // IVOICETWEAK_H diff --git a/sdk/hlsdk/common/mathlib.h b/sdk/hlsdk/common/mathlib.h new file mode 100644 index 0000000..908e631 --- /dev/null +++ b/sdk/hlsdk/common/mathlib.h @@ -0,0 +1,156 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// mathlib.h + +typedef float vec_t; +typedef vec_t vec3_t[3]; +typedef vec_t vec4_t[4]; // x,y,z,w +typedef vec_t vec5_t[5]; + +typedef short vec_s_t; +typedef vec_s_t vec3s_t[3]; +typedef vec_s_t vec4s_t[4]; // x,y,z,w +typedef vec_s_t vec5s_t[5]; + +typedef int fixed4_t; +typedef int fixed8_t; +typedef int fixed16_t; + +#ifndef M_PI +#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h +#endif + +struct mplane_s; + +extern vec3_t vec3_origin; +extern int nanmask; + +#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) + +#ifndef VECTOR_H + #define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) +#endif + +#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];} +#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];} +#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];} +#define VectorClear(a) {(a)[0]=0.0;(a)[1]=0.0;(a)[2]=0.0;} + +void VectorMA (const vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc); + +vec_t _DotProduct (vec3_t v1, vec3_t v2); +void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out); +void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out); +void _VectorCopy (vec3_t in, vec3_t out); + +int VectorCompare (const vec3_t v1, const vec3_t v2); +float Length (const vec3_t v); +void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross); +float VectorNormalize (vec3_t v); // returns vector length +void VectorInverse (vec3_t v); +void VectorScale (const vec3_t in, vec_t scale, vec3_t out); +int Q_log2(int val); + +void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]); +void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]); + +// Here are some "manual" INLINE routines for doing floating point to integer conversions +extern short new_cw, old_cw; + +typedef union DLONG { + int i[2]; + double d; + float f; + } DLONG; + +extern DLONG dlong; + +#ifdef _WIN32 +void __inline set_fpu_cw(void) +{ +_asm + { wait + fnstcw old_cw + wait + mov ax, word ptr old_cw + or ah, 0xc + mov word ptr new_cw,ax + fldcw new_cw + } +} + +int __inline quick_ftol(float f) +{ + _asm { + // Assumes that we are already in chop mode, and only need a 32-bit int + fld DWORD PTR f + fistp DWORD PTR dlong + } + return dlong.i[0]; +} + +void __inline restore_fpu_cw(void) +{ + _asm fldcw old_cw +} +#else +#define set_fpu_cw() /* */ +#define quick_ftol(f) ftol(f) +#define restore_fpu_cw() /* */ +#endif + +void FloorDivMod (double numer, double denom, int *quotient, + int *rem); +fixed16_t Invert24To16(fixed16_t val); +int GreatestCommonDivisor (int i1, int i2); + +void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); +void AngleVectorsTranspose (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); +#define AngleIVectors AngleVectorsTranspose + +void AngleMatrix (const vec3_t angles, float (*matrix)[4] ); +void AngleIMatrix (const vec3_t angles, float (*matrix)[4] ); +void VectorTransform (const vec3_t in1, float in2[3][4], vec3_t out); + +void NormalizeAngles( vec3_t angles ); +void InterpolateAngles( vec3_t start, vec3_t end, vec3_t output, float frac ); +float AngleBetweenVectors( const vec3_t v1, const vec3_t v2 ); + + +void VectorMatrix( vec3_t forward, vec3_t right, vec3_t up); +void VectorAngles( const vec3_t forward, vec3_t angles ); + +int InvertMatrix( const float * m, float *out ); + +int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane); +float anglemod(float a); + + + +#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \ + (((p)->type < 3)? \ + ( \ + ((p)->dist <= (emins)[(p)->type])? \ + 1 \ + : \ + ( \ + ((p)->dist >= (emaxs)[(p)->type])?\ + 2 \ + : \ + 3 \ + ) \ + ) \ + : \ + BoxOnPlaneSide( (emins), (emaxs), (p))) diff --git a/sdk/hlsdk/common/net_api.h b/sdk/hlsdk/common/net_api.h new file mode 100644 index 0000000..df86cca --- /dev/null +++ b/sdk/hlsdk/common/net_api.h @@ -0,0 +1,101 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#if !defined( NET_APIH ) +#define NET_APIH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +#if !defined ( NETADRH ) +#include "netadr.h" +#endif + +#define NETAPI_REQUEST_SERVERLIST ( 0 ) // Doesn't need a remote address +#define NETAPI_REQUEST_PING ( 1 ) +#define NETAPI_REQUEST_RULES ( 2 ) +#define NETAPI_REQUEST_PLAYERS ( 3 ) +#define NETAPI_REQUEST_DETAILS ( 4 ) + +// Set this flag for things like broadcast requests, etc. where the engine should not +// kill the request hook after receiving the first response +#define FNETAPI_MULTIPLE_RESPONSE ( 1<<0 ) + +typedef void ( *net_api_response_func_t ) ( struct net_response_s *response ); + +#define NET_SUCCESS ( 0 ) +#define NET_ERROR_TIMEOUT ( 1<<0 ) +#define NET_ERROR_PROTO_UNSUPPORTED ( 1<<1 ) +#define NET_ERROR_UNDEFINED ( 1<<2 ) + +typedef struct net_adrlist_s +{ + struct net_adrlist_s *next; + netadr_t remote_address; +} net_adrlist_t; + +typedef struct net_response_s +{ + // NET_SUCCESS or an error code + int error; + + // Context ID + int context; + // Type + int type; + + // Server that is responding to the request + netadr_t remote_address; + + // Response RTT ping time + double ping; + // Key/Value pair string ( separated by backlash \ characters ) + // WARNING: You must copy this buffer in the callback function, because it is freed + // by the engine right after the call!!!! + // ALSO: For NETAPI_REQUEST_SERVERLIST requests, this will be a pointer to a linked list of net_adrlist_t's + void *response; +} net_response_t; + +typedef struct net_status_s +{ + // Connected to remote server? 1 == yes, 0 otherwise + int connected; + // Client's IP address + netadr_t local_address; + // Address of remote server + netadr_t remote_address; + // Packet Loss ( as a percentage ) + int packet_loss; + // Latency, in seconds ( multiply by 1000.0 to get milliseconds ) + double latency; + // Connection time, in seconds + double connection_time; + // Rate setting ( for incoming data ) + double rate; +} net_status_t; + +typedef struct net_api_s +{ + // APIs + void ( *InitNetworking )( void ); + void ( *Status ) ( struct net_status_s *status ); + void ( *SendRequest) ( int context, int request, int flags, double timeout, struct netadr_s *remote_address, net_api_response_func_t response ); + void ( *CancelRequest ) ( int context ); + void ( *CancelAllRequests ) ( void ); + char *( *AdrToString ) ( struct netadr_s *a ); + int ( *CompareAdr ) ( struct netadr_s *a, struct netadr_s *b ); + int ( *StringToAdr ) ( char *s, struct netadr_s *a ); + const char *( *ValueForKey ) ( const char *s, const char *key ); + void ( *RemoveKey ) ( char *s, const char *key ); + void ( *SetValueForKey ) (char *s, const char *key, const char *value, int maxsize ); +} net_api_t; + +extern net_api_t netapi; + +#endif // NET_APIH diff --git a/sdk/hlsdk/common/netadr.h b/sdk/hlsdk/common/netadr.h new file mode 100644 index 0000000..f320f93 --- /dev/null +++ b/sdk/hlsdk/common/netadr.h @@ -0,0 +1,42 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// netadr.h +#ifndef NETADR_H +#define NETADR_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +typedef enum +{ + NA_UNUSED, + NA_LOOPBACK, + NA_BROADCAST, + NA_IP, + NA_IPX, + NA_BROADCAST_IPX, +} netadrtype_t; + +typedef struct netadr_s +{ + netadrtype_t type; + unsigned char ip[4]; + unsigned char ipx[10]; + unsigned short port; +} netadr_t; + +#endif // NETADR_H diff --git a/sdk/hlsdk/common/nowin.h b/sdk/hlsdk/common/nowin.h new file mode 100644 index 0000000..fa9863a --- /dev/null +++ b/sdk/hlsdk/common/nowin.h @@ -0,0 +1,15 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef INC_NOWIN_H +#define INC_NOWIN_H +#ifndef _WIN32 + +#include + +#endif //!_WIN32 +#endif //INC_NOWIN_H diff --git a/sdk/hlsdk/common/particledef.h b/sdk/hlsdk/common/particledef.h new file mode 100644 index 0000000..66fc920 --- /dev/null +++ b/sdk/hlsdk/common/particledef.h @@ -0,0 +1,59 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined( PARTICLEDEFH ) +#define PARTICLEDEFH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +typedef enum { + pt_static, + pt_grav, + pt_slowgrav, + pt_fire, + pt_explode, + pt_explode2, + pt_blob, + pt_blob2, + pt_vox_slowgrav, + pt_vox_grav, + pt_clientcustom // Must have callback function specified +} ptype_t; + +// !!! if this is changed, it must be changed in d_ifacea.h too !!! +typedef struct particle_s +{ +// driver-usable fields + vec3_t org; + short color; + short packedColor; +// drivers never touch the following fields + struct particle_s *next; + vec3_t vel; + float ramp; + float die; + ptype_t type; + void (*deathfunc)( struct particle_s *particle ); + + // for pt_clientcusttom, we'll call this function each frame + void (*callback)( struct particle_s *particle, float frametime ); + + // For deathfunc, etc. + unsigned char context; +} particle_t; + +#endif diff --git a/sdk/hlsdk/common/pmtrace.h b/sdk/hlsdk/common/pmtrace.h new file mode 100644 index 0000000..24eb062 --- /dev/null +++ b/sdk/hlsdk/common/pmtrace.h @@ -0,0 +1,45 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined( PMTRACEH ) +#define PMTRACEH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +typedef struct +{ + vec3_t normal; + float dist; +} pmplane_t; + +typedef struct pmtrace_s pmtrace_t; + +struct pmtrace_s +{ + qboolean allsolid; // if true, plane is not valid + qboolean startsolid; // if true, the initial point was in a solid area + qboolean inopen, inwater; // End point is in empty space or in water + float fraction; // time completed, 1.0 = didn't hit anything + vec3_t endpos; // final position + pmplane_t plane; // surface normal at impact + int ent; // entity at impact + vec3_t deltavelocity; // Change in player's velocity caused by impact. + // Only run on server. + int hitgroup; +}; + +#endif diff --git a/sdk/hlsdk/common/qfont.h b/sdk/hlsdk/common/qfont.h new file mode 100644 index 0000000..3866030 --- /dev/null +++ b/sdk/hlsdk/common/qfont.h @@ -0,0 +1,42 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined( QFONTH ) +#define QFONTH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +// Font stuff + +#define NUM_GLYPHS 256 + +typedef struct +{ + short startoffset; + short charwidth; +} charinfo; + +typedef struct qfont_s +{ + int width, height; + int rowcount; + int rowheight; + charinfo fontinfo[ NUM_GLYPHS ]; + byte data[4]; +} qfont_t; + +#endif // qfont.h diff --git a/sdk/hlsdk/common/r_efx.h b/sdk/hlsdk/common/r_efx.h new file mode 100644 index 0000000..3b9aaf5 --- /dev/null +++ b/sdk/hlsdk/common/r_efx.h @@ -0,0 +1,199 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined ( R_EFXH ) +#define R_EFXH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +// particle_t +#if !defined( PARTICLEDEFH ) +#include "particledef.h" +#endif + +// BEAM +#if !defined( BEAMDEFH ) +#include "beamdef.h" +#endif + +// dlight_t +#if !defined ( DLIGHTH ) +#include "dlight.h" +#endif + +// cl_entity_t +#if !defined( CL_ENTITYH ) +#include "cl_entity.h" +#endif + +/* +// FOR REFERENCE, These are the built-in tracer colors. Note, color 4 is the one +// that uses the tracerred/tracergreen/tracerblue and traceralpha cvar settings +color24 gTracerColors[] = +{ + { 255, 255, 255 }, // White + { 255, 0, 0 }, // Red + { 0, 255, 0 }, // Green + { 0, 0, 255 }, // Blue + { 0, 0, 0 }, // Tracer default, filled in from cvars, etc. + { 255, 167, 17 }, // Yellow-orange sparks + { 255, 130, 90 }, // Yellowish streaks (garg) + { 55, 60, 144 }, // Blue egon streak + { 255, 130, 90 }, // More Yellowish streaks (garg) + { 255, 140, 90 }, // More Yellowish streaks (garg) + { 200, 130, 90 }, // More red streaks (garg) + { 255, 120, 70 }, // Darker red streaks (garg) +}; +*/ + +// Temporary entity array +#define TENTPRIORITY_LOW 0 +#define TENTPRIORITY_HIGH 1 + +// TEMPENTITY flags +#define FTENT_NONE 0x00000000 +#define FTENT_SINEWAVE 0x00000001 +#define FTENT_GRAVITY 0x00000002 +#define FTENT_ROTATE 0x00000004 +#define FTENT_SLOWGRAVITY 0x00000008 +#define FTENT_SMOKETRAIL 0x00000010 +#define FTENT_COLLIDEWORLD 0x00000020 +#define FTENT_FLICKER 0x00000040 +#define FTENT_FADEOUT 0x00000080 +#define FTENT_SPRANIMATE 0x00000100 +#define FTENT_HITSOUND 0x00000200 +#define FTENT_SPIRAL 0x00000400 +#define FTENT_SPRCYCLE 0x00000800 +#define FTENT_COLLIDEALL 0x00001000 // will collide with world and slideboxes +#define FTENT_PERSIST 0x00002000 // tent is not removed when unable to draw +#define FTENT_COLLIDEKILL 0x00004000 // tent is removed upon collision with anything +#define FTENT_PLYRATTACHMENT 0x00008000 // tent is attached to a player (owner) +#define FTENT_SPRANIMATELOOP 0x00010000 // animating sprite doesn't die when last frame is displayed +#define FTENT_SPARKSHOWER 0x00020000 +#define FTENT_NOMODEL 0x00040000 // Doesn't have a model, never try to draw ( it just triggers other things ) +#define FTENT_CLIENTCUSTOM 0x00080000 // Must specify callback. Callback function is responsible for killing tempent and updating fields ( unless other flags specify how to do things ) + +typedef struct tempent_s TEMPENTITY; +typedef struct tempent_s +{ + int flags; + float die; + float frameMax; + float x; + float y; + float z; + float fadeSpeed; + float bounceFactor; + int hitSound; + void ( *hitcallback ) ( struct tempent_s *ent, struct pmtrace_s *ptr ); + void ( *callback ) ( struct tempent_s *ent, float frametime, float currenttime ); + TEMPENTITY *next; + int priority; + short clientIndex; // if attached, this is the index of the client to stick to + // if COLLIDEALL, this is the index of the client to ignore + // TENTS with FTENT_PLYRATTACHMENT MUST set the clientindex! + + vec3_t tentOffset; // if attached, client origin + tentOffset = tent origin. + cl_entity_t entity; + + // baseline.origin - velocity + // baseline.renderamt - starting fadeout intensity + // baseline.angles - angle velocity +} TEMPENTITY; + +typedef struct efx_api_s efx_api_t; + +struct efx_api_s +{ + particle_t *( *R_AllocParticle ) ( void ( *callback ) ( struct particle_s *particle, float frametime ) ); + void ( *R_BlobExplosion ) ( float * org ); + void ( *R_Blood ) ( float * org, float * dir, int pcolor, int speed ); + void ( *R_BloodSprite ) ( float * org, int colorindex, int modelIndex, int modelIndex2, float size ); + void ( *R_BloodStream ) ( float * org, float * dir, int pcolor, int speed ); + void ( *R_BreakModel ) ( float *pos, float *size, float *dir, float random, float life, int count, int modelIndex, char flags ); + void ( *R_Bubbles ) ( float * mins, float * maxs, float height, int modelIndex, int count, float speed ); + void ( *R_BubbleTrail ) ( float * start, float * end, float height, int modelIndex, int count, float speed ); + void ( *R_BulletImpactParticles ) ( float * pos ); + void ( *R_EntityParticles ) ( struct cl_entity_s *ent ); + void ( *R_Explosion ) ( float *pos, int model, float scale, float framerate, int flags ); + void ( *R_FizzEffect ) ( struct cl_entity_s *pent, int modelIndex, int density ); + void ( *R_FireField ) ( float * org, int radius, int modelIndex, int count, int flags, float life ); + void ( *R_FlickerParticles ) ( float * org ); + void ( *R_FunnelSprite ) ( float *org, int modelIndex, int reverse ); + void ( *R_Implosion ) ( float * end, float radius, int count, float life ); + void ( *R_LargeFunnel ) ( float * org, int reverse ); + void ( *R_LavaSplash ) ( float * org ); + void ( *R_MultiGunshot ) ( float * org, float * dir, float * noise, int count, int decalCount, int *decalIndices ); + void ( *R_MuzzleFlash ) ( float *pos1, int type ); + void ( *R_ParticleBox ) ( float *mins, float *maxs, unsigned char r, unsigned char g, unsigned char b, float life ); + void ( *R_ParticleBurst ) ( float * pos, int size, int color, float life ); + void ( *R_ParticleExplosion ) ( float * org ); + void ( *R_ParticleExplosion2 ) ( float * org, int colorStart, int colorLength ); + void ( *R_ParticleLine ) ( float * start, float *end, unsigned char r, unsigned char g, unsigned char b, float life ); + void ( *R_PlayerSprites ) ( int client, int modelIndex, int count, int size ); + void ( *R_Projectile ) ( float * origin, float * velocity, int modelIndex, int life, int owner, void (*hitcallback)( struct tempent_s *ent, struct pmtrace_s *ptr ) ); + void ( *R_RicochetSound ) ( float * pos ); + void ( *R_RicochetSprite ) ( float *pos, struct model_s *pmodel, float duration, float scale ); + void ( *R_RocketFlare ) ( float *pos ); + void ( *R_RocketTrail ) ( float * start, float * end, int type ); + void ( *R_RunParticleEffect ) ( float * org, float * dir, int color, int count ); + void ( *R_ShowLine ) ( float * start, float * end ); + void ( *R_SparkEffect ) ( float *pos, int count, int velocityMin, int velocityMax ); + void ( *R_SparkShower ) ( float *pos ); + void ( *R_SparkStreaks ) ( float * pos, int count, int velocityMin, int velocityMax ); + void ( *R_Spray ) ( float * pos, float * dir, int modelIndex, int count, int speed, int spread, int rendermode ); + void ( *R_Sprite_Explode ) ( TEMPENTITY *pTemp, float scale, int flags ); + void ( *R_Sprite_Smoke ) ( TEMPENTITY *pTemp, float scale ); + void ( *R_Sprite_Spray ) ( float * pos, float * dir, int modelIndex, int count, int speed, int iRand ); + void ( *R_Sprite_Trail ) ( int type, float * start, float * end, int modelIndex, int count, float life, float size, float amplitude, int renderamt, float speed ); + void ( *R_Sprite_WallPuff ) ( TEMPENTITY *pTemp, float scale ); + void ( *R_StreakSplash ) ( float * pos, float * dir, int color, int count, float speed, int velocityMin, int velocityMax ); + void ( *R_TracerEffect ) ( float * start, float * end ); + void ( *R_UserTracerParticle ) ( float * org, float * vel, float life, int colorIndex, float length, unsigned char deathcontext, void ( *deathfunc)( struct particle_s *particle ) ); + particle_t *( *R_TracerParticles ) ( float * org, float * vel, float life ); + void ( *R_TeleportSplash ) ( float * org ); + void ( *R_TempSphereModel ) ( float *pos, float speed, float life, int count, int modelIndex ); + TEMPENTITY *( *R_TempModel ) ( float *pos, float *dir, float *angles, float life, int modelIndex, int soundtype ); + TEMPENTITY *( *R_DefaultSprite ) ( float *pos, int spriteIndex, float framerate ); + TEMPENTITY *( *R_TempSprite ) ( float *pos, float *dir, float scale, int modelIndex, int rendermode, int renderfx, float a, float life, int flags ); + int ( *Draw_DecalIndex ) ( int id ); + int ( *Draw_DecalIndexFromName ) ( char *name ); + void ( *R_DecalShoot ) ( int textureIndex, int entity, int modelIndex, float * position, int flags ); + void ( *R_AttachTentToPlayer ) ( int client, int modelIndex, float zoffset, float life ); + void ( *R_KillAttachedTents ) ( int client ); + BEAM *( *R_BeamCirclePoints ) ( int type, float * start, float * end, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b ); + BEAM *( *R_BeamEntPoint ) ( int startEnt, float * end, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b ); + BEAM *( *R_BeamEnts ) ( int startEnt, int endEnt, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b ); + BEAM *( *R_BeamFollow ) ( int startEnt, int modelIndex, float life, float width, float r, float g, float b, float brightness ); + void ( *R_BeamKill ) ( int deadEntity ); + BEAM *( *R_BeamLightning ) ( float * start, float * end, int modelIndex, float life, float width, float amplitude, float brightness, float speed ); + BEAM *( *R_BeamPoints ) ( float * start, float * end, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b ); + BEAM *( *R_BeamRing ) ( int startEnt, int endEnt, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b ); + dlight_t *( *CL_AllocDlight ) ( int key ); + dlight_t *( *CL_AllocElight ) ( int key ); + TEMPENTITY *( *CL_TempEntAlloc ) ( float * org, struct model_s *model ); + TEMPENTITY *( *CL_TempEntAllocNoModel ) ( float * org ); + TEMPENTITY *( *CL_TempEntAllocHigh ) ( float * org, struct model_s *model ); + TEMPENTITY *( *CL_TentEntAllocCustom ) ( float *origin, struct model_s *model, int high, void ( *callback ) ( struct tempent_s *ent, float frametime, float currenttime ) ); + void ( *R_GetPackedColor ) ( short *packed, short color ); + short ( *R_LookupColor ) ( unsigned char r, unsigned char g, unsigned char b ); + void ( *R_DecalRemoveAll ) ( int textureIndex ); //textureIndex points to the decal index in the array, not the actual texture index. +}; + +extern efx_api_t efx; + +#endif diff --git a/sdk/hlsdk/common/r_studioint.h b/sdk/hlsdk/common/r_studioint.h new file mode 100644 index 0000000..bcf2be7 --- /dev/null +++ b/sdk/hlsdk/common/r_studioint.h @@ -0,0 +1,149 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#if !defined( R_STUDIOINT_H ) +#define R_STUDIOINT_H +#if defined( _WIN32 ) +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +#define STUDIO_INTERFACE_VERSION 1 + +typedef struct engine_studio_api_s +{ + // Allocate number*size bytes and zero it + void *( *Mem_Calloc ) ( int number, size_t size ); + // Check to see if pointer is in the cache + void *( *Cache_Check ) ( struct cache_user_s *c ); + // Load file into cache ( can be swapped out on demand ) + void ( *LoadCacheFile ) ( char *path, struct cache_user_s *cu ); + // Retrieve model pointer for the named model + struct model_s *( *Mod_ForName ) ( const char *name, int crash_if_missing ); + // Retrieve pointer to studio model data block from a model + void *( *Mod_Extradata ) ( struct model_s *mod ); + // Retrieve indexed model from client side model precache list + struct model_s *( *GetModelByIndex ) ( int index ); + // Get entity that is set for rendering + struct cl_entity_s * ( *GetCurrentEntity ) ( void ); + // Get referenced player_info_t + struct player_info_s *( *PlayerInfo ) ( int index ); + // Get most recently received player state data from network system + struct entity_state_s *( *GetPlayerState ) ( int index ); + // Get viewentity + struct cl_entity_s * ( *GetViewEntity ) ( void ); + // Get current frame count, and last two timestampes on client + void ( *GetTimes ) ( int *framecount, double *current, double *old ); + // Get a pointer to a cvar by name + struct cvar_s *( *GetCvar ) ( const char *name ); + // Get current render origin and view vectors ( up, right and vpn ) + void ( *GetViewInfo ) ( float *origin, float *upv, float *rightv, float *vpnv ); + // Get sprite model used for applying chrome effect + struct model_s *( *GetChromeSprite ) ( void ); + // Get model counters so we can incement instrumentation + void ( *GetModelCounters ) ( int **s, int **a ); + // Get software scaling coefficients + void ( *GetAliasScale ) ( float *x, float *y ); + + // Get bone, light, alias, and rotation matrices + float ****( *StudioGetBoneTransform ) ( void ); + float ****( *StudioGetLightTransform )( void ); + float ***( *StudioGetAliasTransform ) ( void ); + float ***( *StudioGetRotationMatrix ) ( void ); + + // Set up body part, and get submodel pointers + void ( *StudioSetupModel ) ( int bodypart, void **ppbodypart, void **ppsubmodel ); + // Check if entity's bbox is in the view frustum + int ( *StudioCheckBBox ) ( void ); + // Apply lighting effects to model + void ( *StudioDynamicLight ) ( struct cl_entity_s *ent, struct alight_s *plight ); + void ( *StudioEntityLight ) ( struct alight_s *plight ); + void ( *StudioSetupLighting ) ( struct alight_s *plighting ); + + // Draw mesh vertices + void ( *StudioDrawPoints ) ( void ); + + // Draw hulls around bones + void ( *StudioDrawHulls ) ( void ); + // Draw bbox around studio models + void ( *StudioDrawAbsBBox ) ( void ); + // Draws bones + void ( *StudioDrawBones ) ( void ); + // Loads in appropriate texture for model + void ( *StudioSetupSkin ) ( void *ptexturehdr, int index ); + // Sets up for remapped colors + void ( *StudioSetRemapColors ) ( int top, int bottom ); + // Set's player model and returns model pointer + struct model_s *( *SetupPlayerModel ) ( int index ); + // Fires any events embedded in animation + void ( *StudioClientEvents ) ( void ); + // Retrieve/set forced render effects flags + int ( *GetForceFaceFlags ) ( void ); + void ( *SetForceFaceFlags ) ( int flags ); + // Tell engine the value of the studio model header + void ( *StudioSetHeader ) ( void *header ); + // Tell engine which model_t * is being renderered + void ( *SetRenderModel ) ( struct model_s *model ); + + // Final state setup and restore for rendering + void ( *SetupRenderer ) ( int rendermode ); + void ( *RestoreRenderer ) ( void ); + + // Set render origin for applying chrome effect + void ( *SetChromeOrigin ) ( void ); + + // True if using D3D/OpenGL + int ( *IsHardware ) ( void ); + + // Only called by hardware interface + void ( *GL_StudioDrawShadow ) ( void ); + void ( *GL_SetRenderMode ) ( int mode ); +} engine_studio_api_t; + +typedef struct server_studio_api_s +{ + // Allocate number*size bytes and zero it + void *( *Mem_Calloc ) ( int number, size_t size ); + // Check to see if pointer is in the cache + void *( *Cache_Check ) ( struct cache_user_s *c ); + // Load file into cache ( can be swapped out on demand ) + void ( *LoadCacheFile ) ( char *path, struct cache_user_s *cu ); + // Retrieve pointer to studio model data block from a model + void *( *Mod_Extradata ) ( struct model_s *mod ); +} server_studio_api_t; + + +// client blending +typedef struct r_studio_interface_s +{ + int version; + int ( *StudioDrawModel ) ( int flags ); + int ( *StudioDrawPlayer ) ( int flags, struct entity_state_s *pplayer ); +} r_studio_interface_t; + +extern r_studio_interface_t *pStudioAPI; + +// server blending +#define SV_BLENDING_INTERFACE_VERSION 1 + +typedef struct sv_blending_interface_s +{ + int version; + + void ( *SV_StudioSetupBones )( struct model_s *pModel, + float frame, + int sequence, + const vec3_t angles, + const vec3_t origin, + const byte *pcontroller, + const byte *pblending, + int iBone, + const edict_t *pEdict ); +} sv_blending_interface_t; + +#endif // R_STUDIOINT_H diff --git a/sdk/hlsdk/common/ref_params.h b/sdk/hlsdk/common/ref_params.h new file mode 100644 index 0000000..90eb03f --- /dev/null +++ b/sdk/hlsdk/common/ref_params.h @@ -0,0 +1,75 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined( REF_PARAMSH ) +#define REF_PARAMSH + +typedef struct ref_params_s +{ + // Output + float vieworg[3]; + float viewangles[3]; + + float forward[3]; + float right[3]; + float up[3]; + + // Client frametime; + float frametime; + // Client time + float time; + + // Misc + int intermission; + int paused; + int spectator; + int onground; + int waterlevel; + + float simvel[3]; + float simorg[3]; + + float viewheight[3]; + float idealpitch; + + float cl_viewangles[3]; + + int health; + float crosshairangle[3]; + float viewsize; + + float punchangle[3]; + int maxclients; + int viewentity; + int playernum; + int max_entities; + int demoplayback; + int hardware; + + int smoothing; + + // Last issued usercmd + struct usercmd_s *cmd; + + // Movevars + struct movevars_s *movevars; + + int viewport[4]; // the viewport coordinates x ,y , width, height + + int nextView; // the renderer calls ClientDLL_CalcRefdef() and Renderview + // so long in cycles until this value is 0 (multiple views) + int onlyClientDraw; // if !=0 nothing is drawn by the engine except clientDraw functions +} ref_params_t; + +#endif // !REF_PARAMSH diff --git a/sdk/hlsdk/common/screenfade.h b/sdk/hlsdk/common/screenfade.h new file mode 100644 index 0000000..11223df --- /dev/null +++ b/sdk/hlsdk/common/screenfade.h @@ -0,0 +1,26 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#if !defined( SCREENFADEH ) +#define SCREENFADEH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +typedef struct screenfade_s +{ + float fadeSpeed; // How fast to fade (tics / second) (+ fade in, - fade out) + float fadeEnd; // When the fading hits maximum + float fadeTotalEnd; // Total End Time of the fade (used for FFADE_OUT) + float fadeReset; // When to reset to not fading (for fadeout and hold) + byte fader, fadeg, fadeb, fadealpha; // Fade color + int fadeFlags; // Fading flags +} screenfade_t; + +#endif // !SCREENFADEH diff --git a/sdk/hlsdk/common/studio_event.h b/sdk/hlsdk/common/studio_event.h new file mode 100644 index 0000000..0756c65 --- /dev/null +++ b/sdk/hlsdk/common/studio_event.h @@ -0,0 +1,31 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined( STUDIO_EVENTH ) +#define STUDIO_EVENTH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +typedef struct mstudioevent_s +{ + int frame; + int event; + int type; + char options[64]; +} mstudioevent_t; + +#endif // STUDIO_EVENTH diff --git a/sdk/hlsdk/common/triangleapi.h b/sdk/hlsdk/common/triangleapi.h new file mode 100644 index 0000000..e984cf8 --- /dev/null +++ b/sdk/hlsdk/common/triangleapi.h @@ -0,0 +1,61 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined( TRIANGLEAPIH ) +#define TRIANGLEAPIH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +typedef enum +{ + TRI_FRONT = 0, + TRI_NONE = 1, +} TRICULLSTYLE; + +#define TRI_API_VERSION 1 + +#define TRI_TRIANGLES 0 +#define TRI_TRIANGLE_FAN 1 +#define TRI_QUADS 2 +#define TRI_POLYGON 3 +#define TRI_LINES 4 +#define TRI_TRIANGLE_STRIP 5 +#define TRI_QUAD_STRIP 6 + +typedef struct triangleapi_s +{ + int version; + + void ( *RenderMode )( int mode ); + void ( *Begin )( int primitiveCode ); + void ( *End ) ( void ); + + void ( *Color4f ) ( float r, float g, float b, float a ); + void ( *Color4ub ) ( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); + void ( *TexCoord2f ) ( float u, float v ); + void ( *Vertex3fv ) ( float *worldPnt ); + void ( *Vertex3f ) ( float x, float y, float z ); + void ( *Brightness ) ( float brightness ); + void ( *CullFace ) ( TRICULLSTYLE style ); + int ( *SpriteTexture ) ( struct model_s *pSpriteModel, int frame ); + int ( *WorldToScreen ) ( float *world, float *screen ); // Returns 1 if it's z clipped + void ( *Fog ) ( float flFogColor[3], float flStart, float flEnd, int bOn ); //Works just like GL_FOG, flFogColor is r/g/b. + void ( *ScreenToWorld ) ( float *screen, float *world ); + +} triangleapi_t; + +#endif // !TRIANGLEAPIH diff --git a/sdk/hlsdk/common/usercmd.h b/sdk/hlsdk/common/usercmd.h new file mode 100644 index 0000000..daf78c3 --- /dev/null +++ b/sdk/hlsdk/common/usercmd.h @@ -0,0 +1,43 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef USERCMD_H +#define USERCMD_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +typedef struct usercmd_s +{ + short lerp_msec; // Interpolation time on client + byte msec; // Duration in ms of command + vec3_t viewangles; // Command view angles. + +// intended velocities + float forwardmove; // Forward velocity. + float sidemove; // Sideways velocity. + float upmove; // Upward velocity. + byte lightlevel; // Light level at spot where we are standing. + unsigned short buttons; // Attack buttons + byte impulse; // Impulse command issued. + byte weaponselect; // Current weapon id + +// Experimental player impact stuff. + int impact_index; + vec3_t impact_position; +} usercmd_t; + +#endif // USERCMD_H diff --git a/sdk/hlsdk/common/weaponinfo.h b/sdk/hlsdk/common/weaponinfo.h new file mode 100644 index 0000000..4b6af25 --- /dev/null +++ b/sdk/hlsdk/common/weaponinfo.h @@ -0,0 +1,54 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined ( WEAPONINFOH ) +#define WEAPONINFOH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +// Info about weapons player might have in his/her possession +typedef struct weapon_data_s +{ + int m_iId; + int m_iClip; + + float m_flNextPrimaryAttack; + float m_flNextSecondaryAttack; + float m_flTimeWeaponIdle; + + int m_fInReload; + int m_fInSpecialReload; + float m_flNextReload; + float m_flPumpTime; + float m_fReloadTime; + + float m_fAimedDamage; + float m_fNextAimBonus; + int m_fInZoom; + int m_iWeaponState; + + int iuser1; + int iuser2; + int iuser3; + int iuser4; + float fuser1; + float fuser2; + float fuser3; + float fuser4; +} weapon_data_t; + +#endif diff --git a/sdk/hlsdk/dlls/activity.h b/sdk/hlsdk/dlls/activity.h new file mode 100644 index 0000000..6fd3a18 --- /dev/null +++ b/sdk/hlsdk/dlls/activity.h @@ -0,0 +1,109 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +#ifndef ACTIVITY_H +#define ACTIVITY_H + + +typedef enum { + ACT_RESET = 0, // Set m_Activity to this invalid value to force a reset to m_IdealActivity + ACT_IDLE = 1, + ACT_GUARD, + ACT_WALK, + ACT_RUN, + ACT_FLY, // Fly (and flap if appropriate) + ACT_SWIM, + ACT_HOP, // vertical jump + ACT_LEAP, // long forward jump + ACT_FALL, + ACT_LAND, + ACT_STRAFE_LEFT, + ACT_STRAFE_RIGHT, + ACT_ROLL_LEFT, // tuck and roll, left + ACT_ROLL_RIGHT, // tuck and roll, right + ACT_TURN_LEFT, // turn quickly left (stationary) + ACT_TURN_RIGHT, // turn quickly right (stationary) + ACT_CROUCH, // the act of crouching down from a standing position + ACT_CROUCHIDLE, // holding body in crouched position (loops) + ACT_STAND, // the act of standing from a crouched position + ACT_USE, + ACT_SIGNAL1, + ACT_SIGNAL2, + ACT_SIGNAL3, + ACT_TWITCH, + ACT_COWER, + ACT_SMALL_FLINCH, + ACT_BIG_FLINCH, + ACT_RANGE_ATTACK1, + ACT_RANGE_ATTACK2, + ACT_MELEE_ATTACK1, + ACT_MELEE_ATTACK2, + ACT_RELOAD, + ACT_ARM, // pull out gun, for instance + ACT_DISARM, // reholster gun + ACT_EAT, // monster chowing on a large food item (loop) + ACT_DIESIMPLE, + ACT_DIEBACKWARD, + ACT_DIEFORWARD, + ACT_DIEVIOLENT, + ACT_BARNACLE_HIT, // barnacle tongue hits a monster + ACT_BARNACLE_PULL, // barnacle is lifting the monster ( loop ) + ACT_BARNACLE_CHOMP, // barnacle latches on to the monster + ACT_BARNACLE_CHEW, // barnacle is holding the monster in its mouth ( loop ) + ACT_SLEEP, + ACT_INSPECT_FLOOR, // for active idles, look at something on or near the floor + ACT_INSPECT_WALL, // for active idles, look at something directly ahead of you ( doesn't HAVE to be a wall or on a wall ) + ACT_IDLE_ANGRY, // alternate idle animation in which the monster is clearly agitated. (loop) + ACT_WALK_HURT, // limp (loop) + ACT_RUN_HURT, // limp (loop) + ACT_HOVER, // Idle while in flight + ACT_GLIDE, // Fly (don't flap) + ACT_FLY_LEFT, // Turn left in flight + ACT_FLY_RIGHT, // Turn right in flight + ACT_DETECT_SCENT, // this means the monster smells a scent carried by the air + ACT_SNIFF, // this is the act of actually sniffing an item in front of the monster + ACT_BITE, // some large monsters can eat small things in one bite. This plays one time, EAT loops. + ACT_THREAT_DISPLAY, // without attacking, monster demonstrates that it is angry. (Yell, stick out chest, etc ) + ACT_FEAR_DISPLAY, // monster just saw something that it is afraid of + ACT_EXCITED, // for some reason, monster is excited. Sees something he really likes to eat, or whatever. + ACT_SPECIAL_ATTACK1, // very monster specific special attacks. + ACT_SPECIAL_ATTACK2, + ACT_COMBAT_IDLE, // agitated idle. + ACT_WALK_SCARED, + ACT_RUN_SCARED, + ACT_VICTORY_DANCE, // killed a player, do a victory dance. + ACT_DIE_HEADSHOT, // die, hit in head. + ACT_DIE_CHESTSHOT, // die, hit in chest + ACT_DIE_GUTSHOT, // die, hit in gut + ACT_DIE_BACKSHOT, // die, hit in back + ACT_FLINCH_HEAD, + ACT_FLINCH_CHEST, + ACT_FLINCH_STOMACH, + ACT_FLINCH_LEFTARM, + ACT_FLINCH_RIGHTARM, + ACT_FLINCH_LEFTLEG, + ACT_FLINCH_RIGHTLEG, +} Activity; + + +typedef struct { + int type; + char *name; +} activity_map_t; + +extern activity_map_t activity_map[]; + + +#endif //ACTIVITY_H diff --git a/sdk/hlsdk/dlls/activitymap.h b/sdk/hlsdk/dlls/activitymap.h new file mode 100644 index 0000000..92cadae --- /dev/null +++ b/sdk/hlsdk/dlls/activitymap.h @@ -0,0 +1,97 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +#define _A( a ) { a, #a } + +activity_map_t activity_map[] = +{ +_A( ACT_IDLE ), +_A( ACT_GUARD ), +_A( ACT_WALK ), +_A( ACT_RUN ), +_A( ACT_FLY ), +_A( ACT_SWIM ), +_A( ACT_HOP ), +_A( ACT_LEAP ), +_A( ACT_FALL ), +_A( ACT_LAND ), +_A( ACT_STRAFE_LEFT ), +_A( ACT_STRAFE_RIGHT ), +_A( ACT_ROLL_LEFT ), +_A( ACT_ROLL_RIGHT ), +_A( ACT_TURN_LEFT ), +_A( ACT_TURN_RIGHT ), +_A( ACT_CROUCH ), +_A( ACT_CROUCHIDLE ), +_A( ACT_STAND ), +_A( ACT_USE ), +_A( ACT_SIGNAL1 ), +_A( ACT_SIGNAL2 ), +_A( ACT_SIGNAL3 ), +_A( ACT_TWITCH ), +_A( ACT_COWER ), +_A( ACT_SMALL_FLINCH ), +_A( ACT_BIG_FLINCH ), +_A( ACT_RANGE_ATTACK1 ), +_A( ACT_RANGE_ATTACK2 ), +_A( ACT_MELEE_ATTACK1 ), +_A( ACT_MELEE_ATTACK2 ), +_A( ACT_RELOAD ), +_A( ACT_ARM ), +_A( ACT_DISARM ), +_A( ACT_EAT ), +_A( ACT_DIESIMPLE ), +_A( ACT_DIEBACKWARD ), +_A( ACT_DIEFORWARD ), +_A( ACT_DIEVIOLENT ), +_A( ACT_BARNACLE_HIT ), +_A( ACT_BARNACLE_PULL ), +_A( ACT_BARNACLE_CHOMP ), +_A( ACT_BARNACLE_CHEW ), +_A( ACT_SLEEP ), +_A( ACT_INSPECT_FLOOR ), +_A( ACT_INSPECT_WALL ), +_A( ACT_IDLE_ANGRY ), +_A( ACT_WALK_HURT ), +_A( ACT_RUN_HURT ), +_A( ACT_HOVER ), +_A( ACT_GLIDE ), +_A( ACT_FLY_LEFT ), +_A( ACT_FLY_RIGHT ), +_A( ACT_DETECT_SCENT ), +_A( ACT_SNIFF ), +_A( ACT_BITE ), +_A( ACT_THREAT_DISPLAY ), +_A( ACT_FEAR_DISPLAY ), +_A( ACT_EXCITED ), +_A( ACT_SPECIAL_ATTACK1 ), +_A( ACT_SPECIAL_ATTACK2 ), +_A( ACT_COMBAT_IDLE ), +_A( ACT_WALK_SCARED ), +_A( ACT_RUN_SCARED ), +_A( ACT_VICTORY_DANCE ), +_A( ACT_DIE_HEADSHOT ), +_A( ACT_DIE_CHESTSHOT ), +_A( ACT_DIE_GUTSHOT ), +_A( ACT_DIE_BACKSHOT ), +_A( ACT_FLINCH_HEAD ), +_A( ACT_FLINCH_CHEST ), +_A( ACT_FLINCH_STOMACH ), +_A( ACT_FLINCH_LEFTARM ), +_A( ACT_FLINCH_RIGHTARM ), +_A( ACT_FLINCH_LEFTLEG ), +_A( ACT_FLINCH_RIGHTLEG ), +0, NULL +}; diff --git a/sdk/hlsdk/dlls/animation.h b/sdk/hlsdk/dlls/animation.h new file mode 100644 index 0000000..174bd71 --- /dev/null +++ b/sdk/hlsdk/dlls/animation.h @@ -0,0 +1,47 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef ANIMATION_H +#define ANIMATION_H + +#define ACTIVITY_NOT_AVAILABLE -1 + +#ifndef MONSTEREVENT_H +#include "monsterevent.h" +#endif + +extern int IsSoundEvent( int eventNumber ); + +int LookupActivity( void *pmodel, entvars_t *pev, int activity ); +int LookupActivityHeaviest( void *pmodel, entvars_t *pev, int activity ); +int LookupSequence( void *pmodel, const char *label ); +void GetSequenceInfo( void *pmodel, entvars_t *pev, float *pflFrameRate, float *pflGroundSpeed ); +int GetSequenceFlags( void *pmodel, entvars_t *pev ); +int LookupAnimationEvents( void *pmodel, entvars_t *pev, float flStart, float flEnd ); +float SetController( void *pmodel, entvars_t *pev, int iController, float flValue ); +float SetBlending( void *pmodel, entvars_t *pev, int iBlender, float flValue ); +void GetEyePosition( void *pmodel, float *vecEyePosition ); +void SequencePrecache( void *pmodel, const char *pSequenceName ); +int FindTransition( void *pmodel, int iEndingAnim, int iGoalAnim, int *piDir ); +void SetBodygroup( void *pmodel, entvars_t *pev, int iGroup, int iValue ); +int GetBodygroup( void *pmodel, entvars_t *pev, int iGroup ); + +int GetAnimationEvent( void *pmodel, entvars_t *pev, MonsterEvent_t *pMonsterEvent, float flStart, float flEnd, int index ); +int ExtractBbox( void *pmodel, int sequence, float *mins, float *maxs ); + +// From /engine/studio.h +#define STUDIO_LOOPING 0x0001 + + +#endif //ANIMATION_H diff --git a/sdk/hlsdk/dlls/basemonster.h b/sdk/hlsdk/dlls/basemonster.h new file mode 100644 index 0000000..43a2ed7 --- /dev/null +++ b/sdk/hlsdk/dlls/basemonster.h @@ -0,0 +1,94 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef BASEMONSTER_H +#define BASEMONSTER_H + +class CBaseMonster : public CBaseToggle +{ +public: + Activity m_Activity;// what the monster is doing (animation) + Activity m_IdealActivity;// monster should switch to this activity + int m_LastHitGroup; // the last body region that took damage + int m_bitsDamageType; // what types of damage has monster (player) taken + BYTE m_rgbTimeBasedDamage[CDMG_TIMEBASED]; + MONSTERSTATE m_MonsterState;// monster's current state + MONSTERSTATE m_IdealMonsterState;// monster should change to this state + int m_afConditions; + int m_afMemory; + float m_flNextAttack; // cannot attack again until this time + EHANDLE m_hEnemy; // the entity that the monster is fighting. + EHANDLE m_hTargetEnt; // the entity that the monster is trying to reach + float m_flFieldOfView;// width of monster's field of view ( dot product ) + int m_bloodColor; // color of blood particless + Vector m_HackedGunPos; // HACK until we can query end of gun + Vector m_vecEnemyLKP;// last known position of enemy. (enemy's origin) + + + void KeyValue( KeyValueData *pkvd ); + + void MakeIdealYaw( Vector vecTarget ); + virtual float ChangeYaw ( int speed ); + virtual BOOL HasHumanGibs( void ); + virtual BOOL HasAlienGibs( void ); + virtual void FadeMonster( void ); // Called instead of GibMonster() when gibs are disabled + virtual void GibMonster( void ); + virtual Activity GetDeathActivity ( void ); + Activity GetSmallFlinchActivity( void ); + virtual void BecomeDead( void ); + BOOL ShouldGibMonster( int iGib ); + void CallGibMonster( void ); + virtual BOOL ShouldFadeOnDeath( void ); + BOOL FCheckAITrigger( void );// checks and, if necessary, fires the monster's trigger target. + virtual int IRelationship ( CBaseEntity *pTarget ); + virtual int TakeHealth( float flHealth, int bitsDamageType ); + virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType); + int DeadTakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ); + float DamageForce( float damage ); + virtual void Killed( entvars_t *pevAttacker, int iGib ); + virtual void PainSound ( void ) { return; }; + + void RadiusDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ); + void RadiusDamage(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ); + + inline void SetConditions( int iConditions ) { m_afConditions |= iConditions; } + inline void ClearConditions( int iConditions ) { m_afConditions &= ~iConditions; } + inline BOOL HasConditions( int iConditions ) { if ( m_afConditions & iConditions ) return TRUE; return FALSE; } + inline BOOL HasAllConditions( int iConditions ) { if ( (m_afConditions & iConditions) == iConditions ) return TRUE; return FALSE; } + + inline void Remember( int iMemory ) { m_afMemory |= iMemory; } + inline void Forget( int iMemory ) { m_afMemory &= ~iMemory; } + inline BOOL HasMemory( int iMemory ) { if ( m_afMemory & iMemory ) return TRUE; return FALSE; } + inline BOOL HasAllMemories( int iMemory ) { if ( (m_afMemory & iMemory) == iMemory ) return TRUE; return FALSE; } + + // This will stop animation until you call ResetSequenceInfo() at some point in the future + inline void StopAnimation( void ) { pev->framerate = 0; } + + virtual void ReportAIState( void ); + virtual void MonsterInitDead( void ); // Call after animation/pose is set up + void EXPORT CorpseFallThink( void ); + + virtual void Look ( int iDistance );// basic sight function for monsters + virtual CBaseEntity* BestVisibleEnemy ( void );// finds best visible enemy for attack + CBaseEntity *CheckTraceHullAttack( float flDist, int iDamage, int iDmgType ); + virtual BOOL FInViewCone ( CBaseEntity *pEntity );// see if pEntity is in monster's view cone + virtual BOOL FInViewCone ( Vector *pOrigin );// see if given location is in monster's view cone + void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType); + void MakeDamageBloodDecal ( int cCount, float flNoise, TraceResult *ptr, const Vector &vecDir ); + virtual BOOL IsAlive( void ) { return (pev->deadflag != DEAD_DEAD); } + +}; + + +#endif diff --git a/sdk/hlsdk/dlls/cbase.h b/sdk/hlsdk/dlls/cbase.h new file mode 100644 index 0000000..0474df8 --- /dev/null +++ b/sdk/hlsdk/dlls/cbase.h @@ -0,0 +1,797 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +/* + +Class Hierachy + +CBaseEntity + CBaseDelay + CBaseToggle + CBaseItem + CBaseMonster + CBaseCycler + CBasePlayer + CBaseGroup +*/ + +#define MAX_PATH_SIZE 10 // max number of nodes available for a path. + +// These are caps bits to indicate what an object's capabilities (currently used for save/restore and level transitions) +#define FCAP_CUSTOMSAVE 0x00000001 +#define FCAP_ACROSS_TRANSITION 0x00000002 // should transfer between transitions +#define FCAP_MUST_SPAWN 0x00000004 // Spawn after restore +#define FCAP_DONT_SAVE 0x80000000 // Don't save this +#define FCAP_IMPULSE_USE 0x00000008 // can be used by the player +#define FCAP_CONTINUOUS_USE 0x00000010 // can be used by the player +#define FCAP_ONOFF_USE 0x00000020 // can be used by the player +#define FCAP_DIRECTIONAL_USE 0x00000040 // Player sends +/- 1 when using (currently only tracktrains) +#define FCAP_MASTER 0x00000080 // Can be used to "master" other entities (like multisource) + +// UNDONE: This will ignore transition volumes (trigger_transition), but not the PVS!!! +#define FCAP_FORCE_TRANSITION 0x00000080 // ALWAYS goes across transitions + +#include "saverestore.h" +#include "schedule.h" + +#ifndef MONSTEREVENT_H +#include "monsterevent.h" +#endif + +// C functions for external declarations that call the appropriate C++ methods + +#ifdef _WIN32 +#define EXPORT _declspec( dllexport ) +#else +#define EXPORT /* */ +#endif + +extern "C" EXPORT int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ); +extern "C" EXPORT int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ); + +extern int DispatchSpawn( edict_t *pent ); +extern void DispatchKeyValue( edict_t *pentKeyvalue, KeyValueData *pkvd ); +extern void DispatchTouch( edict_t *pentTouched, edict_t *pentOther ); +extern void DispatchUse( edict_t *pentUsed, edict_t *pentOther ); +extern void DispatchThink( edict_t *pent ); +extern void DispatchBlocked( edict_t *pentBlocked, edict_t *pentOther ); +extern void DispatchSave( edict_t *pent, SAVERESTOREDATA *pSaveData ); +extern int DispatchRestore( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity ); +extern void DispatchObjectCollsionBox( edict_t *pent ); +extern void SaveWriteFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); +extern void SaveReadFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); +extern void SaveGlobalState( SAVERESTOREDATA *pSaveData ); +extern void RestoreGlobalState( SAVERESTOREDATA *pSaveData ); +extern void ResetGlobalState( void ); + +typedef enum { USE_OFF = 0, USE_ON = 1, USE_SET = 2, USE_TOGGLE = 3 } USE_TYPE; + +extern void FireTargets( const char *targetName, CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + +typedef void (CBaseEntity::*BASEPTR)(void); +typedef void (CBaseEntity::*ENTITYFUNCPTR)(CBaseEntity *pOther ); +typedef void (CBaseEntity::*USEPTR)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + +// For CLASSIFY +#define CLASS_NONE 0 +#define CLASS_MACHINE 1 +#define CLASS_PLAYER 2 +#define CLASS_HUMAN_PASSIVE 3 +#define CLASS_HUMAN_MILITARY 4 +#define CLASS_ALIEN_MILITARY 5 +#define CLASS_ALIEN_PASSIVE 6 +#define CLASS_ALIEN_MONSTER 7 +#define CLASS_ALIEN_PREY 8 +#define CLASS_ALIEN_PREDATOR 9 +#define CLASS_INSECT 10 +#define CLASS_PLAYER_ALLY 11 +#define CLASS_PLAYER_BIOWEAPON 12 // hornets and snarks.launched by players +#define CLASS_ALIEN_BIOWEAPON 13 // hornets and snarks.launched by the alien menace +#define CLASS_BARNACLE 99 // special because no one pays attention to it, and it eats a wide cross-section of creatures. + +class CBaseEntity; +class CBaseMonster; +class CBasePlayerItem; +class CSquadMonster; + + +#define SF_NORESPAWN ( 1 << 30 )// !!!set this bit on guns and stuff that should never respawn. + +// +// EHANDLE. Safe way to point to CBaseEntities who may die between frames +// +class EHANDLE +{ +private: + edict_t *m_pent; + int m_serialnumber; +public: + edict_t *Get( void ); + edict_t *Set( edict_t *pent ); + + operator int (); + + operator CBaseEntity *(); + + CBaseEntity * operator = (CBaseEntity *pEntity); + CBaseEntity * operator ->(); +}; + + +// +// Base Entity. All entity types derive from this +// +class CBaseEntity +{ +public: + // Constructor. Set engine to use C/C++ callback functions + // pointers to engine data + entvars_t *pev; // Don't need to save/restore this pointer, the engine resets it + + // path corners + CBaseEntity *m_pGoalEnt;// path corner we are heading towards + CBaseEntity *m_pLink;// used for temporary link-list operations. + + // initialization functions + virtual void Spawn( void ) { return; } + virtual void Precache( void ) { return; } + virtual void KeyValue( KeyValueData* pkvd) { pkvd->fHandled = FALSE; } + virtual int Save( CSave &save ); + virtual int Restore( CRestore &restore ); + virtual int ObjectCaps( void ) { return FCAP_ACROSS_TRANSITION; } + virtual void Activate( void ) {} + + // Setup the object->object collision box (pev->mins / pev->maxs is the object->world collision box) + virtual void SetObjectCollisionBox( void ); + +// Classify - returns the type of group (i.e, "houndeye", or "human military" so that monsters with different classnames +// still realize that they are teammates. (overridden for monsters that form groups) + virtual int Classify ( void ) { return CLASS_NONE; }; + virtual void DeathNotice ( entvars_t *pevChild ) {}// monster maker children use this to tell the monster maker that they have died. + + + static TYPEDESCRIPTION m_SaveData[]; + + virtual void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType); + virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); + virtual int TakeHealth( float flHealth, int bitsDamageType ); + virtual void Killed( entvars_t *pevAttacker, int iGib ); + virtual int BloodColor( void ) { return DONT_BLEED; } + virtual void TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ); + virtual BOOL IsTriggered( CBaseEntity *pActivator ) {return TRUE;} + virtual CBaseMonster *MyMonsterPointer( void ) { return NULL;} + virtual CSquadMonster *MySquadMonsterPointer( void ) { return NULL;} + virtual int GetToggleState( void ) { return TS_AT_TOP; } + virtual void AddPoints( int score, BOOL bAllowNegativeScore ) {} + virtual void AddPointsToTeam( int score, BOOL bAllowNegativeScore ) {} + virtual BOOL AddPlayerItem( CBasePlayerItem *pItem ) { return 0; } + virtual BOOL RemovePlayerItem( CBasePlayerItem *pItem ) { return 0; } + virtual int GiveAmmo( int iAmount, char *szName, int iMax ) { return -1; }; + virtual float GetDelay( void ) { return 0; } + virtual int IsMoving( void ) { return pev->velocity != g_vecZero; } + virtual void OverrideReset( void ) {} + virtual int DamageDecal( int bitsDamageType ); + // This is ONLY used by the node graph to test movement through a door + virtual void SetToggleState( int state ) {} + virtual void StartSneaking( void ) {} + virtual void StopSneaking( void ) {} + virtual BOOL OnControls( entvars_t *onpev ) { return FALSE; } + virtual BOOL IsSneaking( void ) { return FALSE; } + virtual BOOL IsAlive( void ) { return (pev->deadflag == DEAD_NO) && pev->health > 0; } + virtual BOOL IsBSPModel( void ) { return pev->solid == SOLID_BSP || pev->movetype == MOVETYPE_PUSHSTEP; } + virtual BOOL ReflectGauss( void ) { return ( IsBSPModel() && !pev->takedamage ); } + virtual BOOL HasTarget( string_t targetname ) { return FStrEq(STRING(targetname), STRING(pev->targetname) ); } + virtual BOOL IsInWorld( void ); + virtual BOOL IsPlayer( void ) { return FALSE; } + virtual BOOL IsNetClient( void ) { return FALSE; } + virtual const char *TeamID( void ) { return ""; } + + +// virtual void SetActivator( CBaseEntity *pActivator ) {} + virtual CBaseEntity *GetNextTarget( void ); + + // fundamental callbacks + void (CBaseEntity ::*m_pfnThink)(void); + void (CBaseEntity ::*m_pfnTouch)( CBaseEntity *pOther ); + void (CBaseEntity ::*m_pfnUse)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + void (CBaseEntity ::*m_pfnBlocked)( CBaseEntity *pOther ); + + virtual void Think( void ) { if (m_pfnThink) (this->*m_pfnThink)(); }; + virtual void Touch( CBaseEntity *pOther ) { if (m_pfnTouch) (this->*m_pfnTouch)( pOther ); }; + virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) + { + if (m_pfnUse) + (this->*m_pfnUse)( pActivator, pCaller, useType, value ); + } + virtual void Blocked( CBaseEntity *pOther ) { if (m_pfnBlocked) (this->*m_pfnBlocked)( pOther ); }; + + // allow engine to allocate instance data + void *operator new( size_t stAllocateBlock, entvars_t *newpev ) + { + return (void *)ALLOC_PRIVATE(ENT(newpev), stAllocateBlock); + }; + + // don't use this. +#if defined(_MSC_VER) && _MSC_VER >= 1200 // only build this code if MSVC++ 6.0 or higher + void operator delete(void *pMem, entvars_t *pev) + { + pev->flags |= FL_KILLME; + }; +#endif + + void UpdateOnRemove( void ); + + // common member functions + void EXPORT SUB_Remove( void ); + void EXPORT SUB_DoNothing( void ); + void EXPORT SUB_StartFadeOut ( void ); + void EXPORT SUB_FadeOut ( void ); + void EXPORT SUB_CallUseToggle( void ) { this->Use( this, this, USE_TOGGLE, 0 ); } + int ShouldToggle( USE_TYPE useType, BOOL currentState ); + void FireBullets( ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq = 4, int iDamage = 0, entvars_t *pevAttacker = NULL ); + Vector FireBulletsPlayer( ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq = 4, int iDamage = 0, entvars_t *pevAttacker = NULL, int shared_rand = 0 ); + + virtual CBaseEntity *Respawn( void ) { return NULL; } + + void SUB_UseTargets( CBaseEntity *pActivator, USE_TYPE useType, float value ); + // Do the bounding boxes of these two intersect? + int Intersects( CBaseEntity *pOther ); + void MakeDormant( void ); + int IsDormant( void ); + BOOL IsLockedByMaster( void ) { return FALSE; } + + static CBaseEntity *Instance( edict_t *pent ) + { + if ( !pent ) + pent = ENT(0); + CBaseEntity *pEnt = (CBaseEntity *)GET_PRIVATE(pent); + return pEnt; + } + + static CBaseEntity *Instance( entvars_t *instpev ) { return Instance( ENT( instpev ) ); } + static CBaseEntity *Instance( int inst_eoffset) { return Instance( ENT( inst_eoffset) ); } + + CBaseMonster *GetMonsterPointer( entvars_t *pevMonster ) + { + CBaseEntity *pEntity = Instance( pevMonster ); + if ( pEntity ) + return pEntity->MyMonsterPointer(); + return NULL; + } + CBaseMonster *GetMonsterPointer( edict_t *pentMonster ) + { + CBaseEntity *pEntity = Instance( pentMonster ); + if ( pEntity ) + return pEntity->MyMonsterPointer(); + return NULL; + } + + + // Ugly code to lookup all functions to make sure they are exported when set. +#ifdef _DEBUG + void FunctionCheck( void *pFunction, char *name ) + { + if (pFunction && !NAME_FOR_FUNCTION((unsigned long)(pFunction)) ) + ALERT( at_error, "No EXPORT: %s:%s (%08lx)\n", STRING(pev->classname), name, (unsigned long)pFunction ); + } + + BASEPTR ThinkSet( BASEPTR func, char *name ) + { + m_pfnThink = func; + FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnThink)))), name ); + return func; + } + ENTITYFUNCPTR TouchSet( ENTITYFUNCPTR func, char *name ) + { + m_pfnTouch = func; + FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnTouch)))), name ); + return func; + } + USEPTR UseSet( USEPTR func, char *name ) + { + m_pfnUse = func; + FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnUse)))), name ); + return func; + } + ENTITYFUNCPTR BlockedSet( ENTITYFUNCPTR func, char *name ) + { + m_pfnBlocked = func; + FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnBlocked)))), name ); + return func; + } + +#endif + + + // virtual functions used by a few classes + + // used by monsters that are created by the MonsterMaker + virtual void UpdateOwner( void ) { return; }; + + + // + static CBaseEntity *Create( char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner = NULL ); + + virtual BOOL FBecomeProne( void ) {return FALSE;}; + edict_t *edict() { return ENT( pev ); }; + EOFFSET eoffset( ) { return OFFSET( pev ); }; + int entindex( ) { return ENTINDEX( edict() ); }; + + virtual Vector Center( ) { return (pev->absmax + pev->absmin) * 0.5; }; // center point of entity + virtual Vector EyePosition( ) { return pev->origin + pev->view_ofs; }; // position of eyes + virtual Vector EarPosition( ) { return pev->origin + pev->view_ofs; }; // position of ears + virtual Vector BodyTarget( const Vector &posSrc ) { return Center( ); }; // position to shoot at + + virtual int Illumination( ) { return GETENTITYILLUM( ENT( pev ) ); }; + + virtual BOOL FVisible ( CBaseEntity *pEntity ); + virtual BOOL FVisible ( const Vector &vecOrigin ); + + //We use this variables to store each ammo count. + int ammo_9mm; + int ammo_357; + int ammo_bolts; + int ammo_buckshot; + int ammo_rockets; + int ammo_uranium; + int ammo_hornets; + int ammo_argrens; + //Special stuff for grenades and satchels. + float m_flStartThrow; + float m_flReleaseThrow; + int m_chargeReady; + int m_fInAttack; + + enum EGON_FIRESTATE { FIRE_OFF, FIRE_CHARGE }; + int m_fireState; +}; + + + +// Ugly technique to override base member functions +// Normally it's illegal to cast a pointer to a member function of a derived class to a pointer to a +// member function of a base class. static_cast is a sleezy way around that problem. + +#ifdef _DEBUG + +#define SetThink( a ) ThinkSet( static_cast (a), #a ) +#define SetTouch( a ) TouchSet( static_cast (a), #a ) +#define SetUse( a ) UseSet( static_cast (a), #a ) +#define SetBlocked( a ) BlockedSet( static_cast (a), #a ) + +#else + +#define SetThink( a ) m_pfnThink = static_cast (a) +#define SetTouch( a ) m_pfnTouch = static_cast (a) +#define SetUse( a ) m_pfnUse = static_cast (a) +#define SetBlocked( a ) m_pfnBlocked = static_cast (a) + +#endif + + +class CPointEntity : public CBaseEntity +{ +public: + void Spawn( void ); + virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } +private: +}; + + +typedef struct locksounds // sounds that doors and buttons make when locked/unlocked +{ + string_t sLockedSound; // sound a door makes when it's locked + string_t sLockedSentence; // sentence group played when door is locked + string_t sUnlockedSound; // sound a door makes when it's unlocked + string_t sUnlockedSentence; // sentence group played when door is unlocked + + int iLockedSentence; // which sentence in sentence group to play next + int iUnlockedSentence; // which sentence in sentence group to play next + + float flwaitSound; // time delay between playing consecutive 'locked/unlocked' sounds + float flwaitSentence; // time delay between playing consecutive sentences + BYTE bEOFLocked; // true if hit end of list of locked sentences + BYTE bEOFUnlocked; // true if hit end of list of unlocked sentences +} locksound_t; + +void PlayLockSounds(entvars_t *pev, locksound_t *pls, int flocked, int fbutton); + +// +// MultiSouce +// + +#define MAX_MULTI_TARGETS 16 // maximum number of targets a single multi_manager entity may be assigned. +#define MS_MAX_TARGETS 32 + +class CMultiSource : public CPointEntity +{ +public: + void Spawn( ); + void KeyValue( KeyValueData *pkvd ); + void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + int ObjectCaps( void ) { return (CPointEntity::ObjectCaps() | FCAP_MASTER); } + BOOL IsTriggered( CBaseEntity *pActivator ); + void EXPORT Register( void ); + virtual int Save( CSave &save ); + virtual int Restore( CRestore &restore ); + + static TYPEDESCRIPTION m_SaveData[]; + + EHANDLE m_rgEntities[MS_MAX_TARGETS]; + int m_rgTriggered[MS_MAX_TARGETS]; + + int m_iTotal; + string_t m_globalstate; +}; + + +// +// generic Delay entity. +// +class CBaseDelay : public CBaseEntity +{ +public: + float m_flDelay; + int m_iszKillTarget; + + virtual void KeyValue( KeyValueData* pkvd); + virtual int Save( CSave &save ); + virtual int Restore( CRestore &restore ); + + static TYPEDESCRIPTION m_SaveData[]; + // common member functions + void SUB_UseTargets( CBaseEntity *pActivator, USE_TYPE useType, float value ); + void EXPORT DelayThink( void ); +}; + + +class CBaseAnimating : public CBaseDelay +{ +public: + virtual int Save( CSave &save ); + virtual int Restore( CRestore &restore ); + + static TYPEDESCRIPTION m_SaveData[]; + + // Basic Monster Animation functions + float StudioFrameAdvance( float flInterval = 0.0 ); // accumulate animation frame time from last time called until now + int GetSequenceFlags( void ); + int LookupActivity ( int activity ); + int LookupActivityHeaviest ( int activity ); + int LookupSequence ( const char *label ); + void ResetSequenceInfo ( ); + void DispatchAnimEvents ( float flFutureInterval = 0.1 ); // Handle events that have happend since last time called up until X seconds into the future + virtual void HandleAnimEvent( MonsterEvent_t *pEvent ) { return; }; + float SetBoneController ( int iController, float flValue ); + void InitBoneControllers ( void ); + float SetBlending ( int iBlender, float flValue ); + void GetBonePosition ( int iBone, Vector &origin, Vector &angles ); + void GetAutomovement( Vector &origin, Vector &angles, float flInterval = 0.1 ); + int FindTransition( int iEndingSequence, int iGoalSequence, int *piDir ); + void GetAttachment ( int iAttachment, Vector &origin, Vector &angles ); + void SetBodygroup( int iGroup, int iValue ); + int GetBodygroup( int iGroup ); + int ExtractBbox( int sequence, float *mins, float *maxs ); + void SetSequenceBox( void ); + + // animation needs + float m_flFrameRate; // computed FPS for current sequence + float m_flGroundSpeed; // computed linear movement rate for current sequence + float m_flLastEventCheck; // last time the event list was checked + BOOL m_fSequenceFinished;// flag set when StudioAdvanceFrame moves across a frame boundry + BOOL m_fSequenceLoops; // true if the sequence loops +}; + + +// +// generic Toggle entity. +// +#define SF_ITEM_USE_ONLY 256 // ITEM_USE_ONLY = BUTTON_USE_ONLY = DOOR_USE_ONLY!!! + +class CBaseToggle : public CBaseAnimating +{ +public: + void KeyValue( KeyValueData *pkvd ); + + TOGGLE_STATE m_toggle_state; + float m_flActivateFinished;//like attack_finished, but for doors + float m_flMoveDistance;// how far a door should slide or rotate + float m_flWait; + float m_flLip; + float m_flTWidth;// for plats + float m_flTLength;// for plats + + Vector m_vecPosition1; + Vector m_vecPosition2; + Vector m_vecAngle1; + Vector m_vecAngle2; + + int m_cTriggersLeft; // trigger_counter only, # of activations remaining + float m_flHeight; + EHANDLE m_hActivator; + void (CBaseToggle::*m_pfnCallWhenMoveDone)(void); + Vector m_vecFinalDest; + Vector m_vecFinalAngle; + + int m_bitsDamageInflict; // DMG_ damage type that the door or tigger does + + virtual int Save( CSave &save ); + virtual int Restore( CRestore &restore ); + + static TYPEDESCRIPTION m_SaveData[]; + + virtual int GetToggleState( void ) { return m_toggle_state; } + virtual float GetDelay( void ) { return m_flWait; } + + // common member functions + void LinearMove( Vector vecDest, float flSpeed ); + void EXPORT LinearMoveDone( void ); + void AngularMove( Vector vecDestAngle, float flSpeed ); + void EXPORT AngularMoveDone( void ); + BOOL IsLockedByMaster( void ); + + static float AxisValue( int flags, const Vector &angles ); + static void AxisDir( entvars_t *pev ); + static float AxisDelta( int flags, const Vector &angle1, const Vector &angle2 ); + + string_t m_sMaster; // If this button has a master switch, this is the targetname. + // A master switch must be of the multisource type. If all + // of the switches in the multisource have been triggered, then + // the button will be allowed to operate. Otherwise, it will be + // deactivated. +}; +#define SetMoveDone( a ) m_pfnCallWhenMoveDone = static_cast (a) + + +// people gib if their health is <= this at the time of death +#define GIB_HEALTH_VALUE -30 + +#define ROUTE_SIZE 8 // how many waypoints a monster can store at one time +#define MAX_OLD_ENEMIES 4 // how many old enemies to remember + +#define bits_CAP_DUCK ( 1 << 0 )// crouch +#define bits_CAP_JUMP ( 1 << 1 )// jump/leap +#define bits_CAP_STRAFE ( 1 << 2 )// strafe ( walk/run sideways) +#define bits_CAP_SQUAD ( 1 << 3 )// can form squads +#define bits_CAP_SWIM ( 1 << 4 )// proficiently navigate in water +#define bits_CAP_CLIMB ( 1 << 5 )// climb ladders/ropes +#define bits_CAP_USE ( 1 << 6 )// open doors/push buttons/pull levers +#define bits_CAP_HEAR ( 1 << 7 )// can hear forced sounds +#define bits_CAP_AUTO_DOORS ( 1 << 8 )// can trigger auto doors +#define bits_CAP_OPEN_DOORS ( 1 << 9 )// can open manual doors +#define bits_CAP_TURN_HEAD ( 1 << 10)// can turn head, always bone controller 0 + +#define bits_CAP_RANGE_ATTACK1 ( 1 << 11)// can do a range attack 1 +#define bits_CAP_RANGE_ATTACK2 ( 1 << 12)// can do a range attack 2 +#define bits_CAP_MELEE_ATTACK1 ( 1 << 13)// can do a melee attack 1 +#define bits_CAP_MELEE_ATTACK2 ( 1 << 14)// can do a melee attack 2 + +#define bits_CAP_FLY ( 1 << 15)// can fly, move all around + +#define bits_CAP_DOORS_GROUP (bits_CAP_USE | bits_CAP_AUTO_DOORS | bits_CAP_OPEN_DOORS) + +// used by suit voice to indicate damage sustained and repaired type to player + +// instant damage + +#define DMG_GENERIC 0 // generic damage was done +#define DMG_CRUSH (1 << 0) // crushed by falling or moving object +#define DMG_BULLET (1 << 1) // shot +#define DMG_SLASH (1 << 2) // cut, clawed, stabbed +#define DMG_BURN (1 << 3) // heat burned +#define DMG_FREEZE (1 << 4) // frozen +#define DMG_FALL (1 << 5) // fell too far +#define DMG_BLAST (1 << 6) // explosive blast damage +#define DMG_CLUB (1 << 7) // crowbar, punch, headbutt +#define DMG_SHOCK (1 << 8) // electric shock +#define DMG_SONIC (1 << 9) // sound pulse shockwave +#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam +#define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death +#define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death. +#define DMG_DROWN (1 << 14) // Drowning +// time-based damage +#define DMG_TIMEBASED (~(0x3fff)) // mask for time-based damage + +#define DMG_PARALYZE (1 << 15) // slows affected creature down +#define DMG_NERVEGAS (1 << 16) // nerve toxins, very bad +#define DMG_POISON (1 << 17) // blood poisioning +#define DMG_RADIATION (1 << 18) // radiation exposure +#define DMG_DROWNRECOVER (1 << 19) // drowning recovery +#define DMG_ACID (1 << 20) // toxic chemicals or acid burns +#define DMG_SLOWBURN (1 << 21) // in an oven +#define DMG_SLOWFREEZE (1 << 22) // in a subzero freezer +#define DMG_MORTAR (1 << 23) // Hit by air raid (done to distinguish grenade from mortar) + +// these are the damage types that are allowed to gib corpses +#define DMG_GIB_CORPSE ( DMG_CRUSH | DMG_FALL | DMG_BLAST | DMG_SONIC | DMG_CLUB ) + +// these are the damage types that have client hud art +#define DMG_SHOWNHUD (DMG_POISON | DMG_ACID | DMG_FREEZE | DMG_SLOWFREEZE | DMG_DROWN | DMG_BURN | DMG_SLOWBURN | DMG_NERVEGAS | DMG_RADIATION | DMG_SHOCK) + +// NOTE: tweak these values based on gameplay feedback: + +#define PARALYZE_DURATION 2 // number of 2 second intervals to take damage +#define PARALYZE_DAMAGE 1.0 // damage to take each 2 second interval + +#define NERVEGAS_DURATION 2 +#define NERVEGAS_DAMAGE 5.0 + +#define POISON_DURATION 5 +#define POISON_DAMAGE 2.0 + +#define RADIATION_DURATION 2 +#define RADIATION_DAMAGE 1.0 + +#define ACID_DURATION 2 +#define ACID_DAMAGE 5.0 + +#define SLOWBURN_DURATION 2 +#define SLOWBURN_DAMAGE 1.0 + +#define SLOWFREEZE_DURATION 2 +#define SLOWFREEZE_DAMAGE 1.0 + + +#define itbd_Paralyze 0 +#define itbd_NerveGas 1 +#define itbd_Poison 2 +#define itbd_Radiation 3 +#define itbd_DrownRecover 4 +#define itbd_Acid 5 +#define itbd_SlowBurn 6 +#define itbd_SlowFreeze 7 +#define CDMG_TIMEBASED 8 + +// when calling KILLED(), a value that governs gib behavior is expected to be +// one of these three values +#define GIB_NORMAL 0// gib if entity was overkilled +#define GIB_NEVER 1// never gib, no matter how much death damage is done ( freezing, etc ) +#define GIB_ALWAYS 2// always gib ( Houndeye Shock, Barnacle Bite ) + +class CBaseMonster; +class CCineMonster; +class CSound; + +#include "basemonster.h" + + +char *ButtonSound( int sound ); // get string of button sound number + + +// +// Generic Button +// +class CBaseButton : public CBaseToggle +{ +public: + void Spawn( void ); + virtual void Precache( void ); + void RotSpawn( void ); + virtual void KeyValue( KeyValueData* pkvd); + + void ButtonActivate( ); + void SparkSoundCache( void ); + + void EXPORT ButtonShot( void ); + void EXPORT ButtonTouch( CBaseEntity *pOther ); + void EXPORT ButtonSpark ( void ); + void EXPORT TriggerAndWait( void ); + void EXPORT ButtonReturn( void ); + void EXPORT ButtonBackHome( void ); + void EXPORT ButtonUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); + virtual int Save( CSave &save ); + virtual int Restore( CRestore &restore ); + + enum BUTTON_CODE { BUTTON_NOTHING, BUTTON_ACTIVATE, BUTTON_RETURN }; + BUTTON_CODE ButtonResponseToTouch( void ); + + static TYPEDESCRIPTION m_SaveData[]; + // Buttons that don't take damage can be IMPULSE used + virtual int ObjectCaps( void ) { return (CBaseToggle:: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | (pev->takedamage?0:FCAP_IMPULSE_USE); } + + BOOL m_fStayPushed; // button stays pushed in until touched again? + BOOL m_fRotating; // a rotating button? default is a sliding button. + + string_t m_strChangeTarget; // if this field is not null, this is an index into the engine string array. + // when this button is touched, it's target entity's TARGET field will be set + // to the button's ChangeTarget. This allows you to make a func_train switch paths, etc. + + locksound_t m_ls; // door lock sounds + + BYTE m_bLockedSound; // ordinals from entity selection + BYTE m_bLockedSentence; + BYTE m_bUnlockedSound; + BYTE m_bUnlockedSentence; + int m_sounds; +}; + +// +// Weapons +// + +#define BAD_WEAPON 0x00007FFF + +// +// Converts a entvars_t * to a class pointer +// It will allocate the class and entity if necessary +// +template T * GetClassPtr( T *a ) +{ + entvars_t *pev = (entvars_t *)a; + + // allocate entity if necessary + if (pev == NULL) + pev = VARS(CREATE_ENTITY()); + + // get the private data + a = (T *)GET_PRIVATE(ENT(pev)); + + if (a == NULL) + { + // allocate private data + a = new(pev) T; + a->pev = pev; + } + return a; +} + + +/* +bit_PUSHBRUSH_DATA | bit_TOGGLE_DATA +bit_MONSTER_DATA +bit_DELAY_DATA +bit_TOGGLE_DATA | bit_DELAY_DATA | bit_MONSTER_DATA +bit_PLAYER_DATA | bit_MONSTER_DATA +bit_MONSTER_DATA | CYCLER_DATA +bit_LIGHT_DATA +path_corner_data +bit_MONSTER_DATA | wildcard_data +bit_MONSTER_DATA | bit_GROUP_DATA +boid_flock_data +boid_data +CYCLER_DATA +bit_ITEM_DATA +bit_ITEM_DATA | func_hud_data +bit_TOGGLE_DATA | bit_ITEM_DATA +EOFFSET +env_sound_data +env_sound_data +push_trigger_data +*/ + +#define TRACER_FREQ 4 // Tracers fire every 4 bullets + +typedef struct _SelAmmo +{ + BYTE Ammo1Type; + BYTE Ammo1; + BYTE Ammo2Type; + BYTE Ammo2; +} SelAmmo; + + +// this moved here from world.cpp, to allow classes to be derived from it +//======================= +// CWorld +// +// This spawns first when each level begins. +//======================= +class CWorld : public CBaseEntity +{ +public: + void Spawn( void ); + void Precache( void ); + void KeyValue( KeyValueData *pkvd ); +}; diff --git a/sdk/hlsdk/dlls/cdll_dll.h b/sdk/hlsdk/dlls/cdll_dll.h new file mode 100644 index 0000000..72b79bd --- /dev/null +++ b/sdk/hlsdk/dlls/cdll_dll.h @@ -0,0 +1,45 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// +// cdll_dll.h + +// this file is included by both the game-dll and the client-dll, + +#ifndef CDLL_DLL_H +#define CDLL_DLL_H + +#define MAX_WEAPONS 32 // ??? + +#define MAX_WEAPON_SLOTS 5 // hud item selection slots +#define MAX_ITEM_TYPES 6 // hud item selection slots + +#define MAX_ITEMS 5 // hard coded item types + +#define HIDEHUD_WEAPONS ( 1<<0 ) +#define HIDEHUD_FLASHLIGHT ( 1<<1 ) +#define HIDEHUD_ALL ( 1<<2 ) +#define HIDEHUD_HEALTH ( 1<<3 ) + +#define MAX_AMMO_TYPES 32 // ??? +#define MAX_AMMO_SLOTS 32 // not really slots + +#define HUD_PRINTNOTIFY 1 +#define HUD_PRINTCONSOLE 2 +#define HUD_PRINTTALK 3 +#define HUD_PRINTCENTER 4 + +#define WEAPON_SUIT 31 + +#endif diff --git a/sdk/hlsdk/dlls/client.h b/sdk/hlsdk/dlls/client.h new file mode 100644 index 0000000..1e66cc8 --- /dev/null +++ b/sdk/hlsdk/dlls/client.h @@ -0,0 +1,65 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef CLIENT_H +#define CLIENT_H + +extern void respawn( entvars_t* pev, BOOL fCopyCorpse ); +extern BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); +extern void ClientDisconnect( edict_t *pEntity ); +extern void ClientKill( edict_t *pEntity ); +extern void ClientPutInServer( edict_t *pEntity ); +extern void ClientCommand( edict_t *pEntity ); +extern void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ); +extern void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ); +extern void ServerDeactivate( void ); +extern void StartFrame( void ); +extern void PlayerPostThink( edict_t *pEntity ); +extern void PlayerPreThink( edict_t *pEntity ); +extern void ParmsNewLevel( void ); +extern void ParmsChangeLevel( void ); + +extern void ClientPrecache( void ); + +extern const char *GetGameDescription( void ); +extern void PlayerCustomization( edict_t *pEntity, customization_t *pCust ); + +extern void SpectatorConnect ( edict_t *pEntity ); +extern void SpectatorDisconnect ( edict_t *pEntity ); +extern void SpectatorThink ( edict_t *pEntity ); + +extern void Sys_Error( const char *error_string ); + +extern void SetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas ); +extern void UpdateClientData ( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd ); +extern int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet ); +extern void CreateBaseline( int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs ); +extern void RegisterEncoders( void ); + +extern int GetWeaponData( struct edict_s *player, struct weapon_data_s *info ); + +extern void CmdStart( const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed ); +extern void CmdEnd ( const edict_t *player ); + +extern int ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); + +extern int GetHullBounds( int hullnumber, float *mins, float *maxs ); + +extern void CreateInstancedBaselines ( void ); + +extern int InconsistentFile( const edict_t *player, const char *filename, char *disconnect_message ); + +extern int AllowLagCompensation( void ); + +#endif // CLIENT_H diff --git a/sdk/hlsdk/dlls/decals.h b/sdk/hlsdk/dlls/decals.h new file mode 100644 index 0000000..95fa44f --- /dev/null +++ b/sdk/hlsdk/dlls/decals.h @@ -0,0 +1,75 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef DECALS_H +#define DECALS_H + +// +// Dynamic Decals +// +enum decal_e +{ + DECAL_GUNSHOT1 = 0, + DECAL_GUNSHOT2, + DECAL_GUNSHOT3, + DECAL_GUNSHOT4, + DECAL_GUNSHOT5, + DECAL_LAMBDA1, + DECAL_LAMBDA2, + DECAL_LAMBDA3, + DECAL_LAMBDA4, + DECAL_LAMBDA5, + DECAL_LAMBDA6, + DECAL_SCORCH1, + DECAL_SCORCH2, + DECAL_BLOOD1, + DECAL_BLOOD2, + DECAL_BLOOD3, + DECAL_BLOOD4, + DECAL_BLOOD5, + DECAL_BLOOD6, + DECAL_YBLOOD1, + DECAL_YBLOOD2, + DECAL_YBLOOD3, + DECAL_YBLOOD4, + DECAL_YBLOOD5, + DECAL_YBLOOD6, + DECAL_GLASSBREAK1, + DECAL_GLASSBREAK2, + DECAL_GLASSBREAK3, + DECAL_BIGSHOT1, + DECAL_BIGSHOT2, + DECAL_BIGSHOT3, + DECAL_BIGSHOT4, + DECAL_BIGSHOT5, + DECAL_SPIT1, + DECAL_SPIT2, + DECAL_BPROOF1, // Bulletproof glass decal + DECAL_GARGSTOMP1, // Gargantua stomp crack + DECAL_SMALLSCORCH1, // Small scorch mark + DECAL_SMALLSCORCH2, // Small scorch mark + DECAL_SMALLSCORCH3, // Small scorch mark + DECAL_MOMMABIRTH, // Big momma birth splatter + DECAL_MOMMASPLAT, +}; + +typedef struct +{ + char *name; + int index; +} DLL_DECALLIST; + +extern DLL_DECALLIST gDecals[]; + +#endif // DECALS_H diff --git a/sdk/hlsdk/dlls/doors.h b/sdk/hlsdk/dlls/doors.h new file mode 100644 index 0000000..8008861 --- /dev/null +++ b/sdk/hlsdk/dlls/doors.h @@ -0,0 +1,33 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef DOORS_H +#define DOORS_H + +// doors +#define SF_DOOR_ROTATE_Y 0 +#define SF_DOOR_START_OPEN 1 +#define SF_DOOR_ROTATE_BACKWARDS 2 +#define SF_DOOR_PASSABLE 8 +#define SF_DOOR_ONEWAY 16 +#define SF_DOOR_NO_AUTO_RETURN 32 +#define SF_DOOR_ROTATE_Z 64 +#define SF_DOOR_ROTATE_X 128 +#define SF_DOOR_USE_ONLY 256 // door must be opened by player's use button. +#define SF_DOOR_NOMONSTERS 512 // Monster can't open +#define SF_DOOR_SILENT 0x80000000 + + + +#endif //DOORS_H diff --git a/sdk/hlsdk/dlls/effects.h b/sdk/hlsdk/dlls/effects.h new file mode 100644 index 0000000..1467b2f --- /dev/null +++ b/sdk/hlsdk/dlls/effects.h @@ -0,0 +1,209 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef EFFECTS_H +#define EFFECTS_H + +#define SF_BEAM_STARTON 0x0001 +#define SF_BEAM_TOGGLE 0x0002 +#define SF_BEAM_RANDOM 0x0004 +#define SF_BEAM_RING 0x0008 +#define SF_BEAM_SPARKSTART 0x0010 +#define SF_BEAM_SPARKEND 0x0020 +#define SF_BEAM_DECALS 0x0040 +#define SF_BEAM_SHADEIN 0x0080 +#define SF_BEAM_SHADEOUT 0x0100 +#define SF_BEAM_TEMPORARY 0x8000 + +#define SF_SPRITE_STARTON 0x0001 +#define SF_SPRITE_ONCE 0x0002 +#define SF_SPRITE_TEMPORARY 0x8000 + +class CSprite : public CPointEntity +{ +public: + void Spawn( void ); + void Precache( void ); + + int ObjectCaps( void ) + { + int flags = 0; + if ( pev->spawnflags & SF_SPRITE_TEMPORARY ) + flags = FCAP_DONT_SAVE; + return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | flags; + } + void EXPORT AnimateThink( void ); + void EXPORT ExpandThink( void ); + void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + void Animate( float frames ); + void Expand( float scaleSpeed, float fadeSpeed ); + void SpriteInit( const char *pSpriteName, const Vector &origin ); + + inline void SetAttachment( edict_t *pEntity, int attachment ) + { + if ( pEntity ) + { + pev->skin = ENTINDEX(pEntity); + pev->body = attachment; + pev->aiment = pEntity; + pev->movetype = MOVETYPE_FOLLOW; + } + } + void TurnOff( void ); + void TurnOn( void ); + inline float Frames( void ) { return m_maxFrame; } + inline void SetTransparency( int rendermode, int r, int g, int b, int a, int fx ) + { + pev->rendermode = rendermode; + pev->rendercolor.x = r; + pev->rendercolor.y = g; + pev->rendercolor.z = b; + pev->renderamt = a; + pev->renderfx = fx; + } + inline void SetTexture( int spriteIndex ) { pev->modelindex = spriteIndex; } + inline void SetScale( float scale ) { pev->scale = scale; } + inline void SetColor( int r, int g, int b ) { pev->rendercolor.x = r; pev->rendercolor.y = g; pev->rendercolor.z = b; } + inline void SetBrightness( int brightness ) { pev->renderamt = brightness; } + + inline void AnimateAndDie( float framerate ) + { + SetThink(AnimateUntilDead); + pev->framerate = framerate; + pev->dmgtime = gpGlobals->time + (m_maxFrame / framerate); + pev->nextthink = gpGlobals->time; + } + + void EXPORT AnimateUntilDead( void ); + + virtual int Save( CSave &save ); + virtual int Restore( CRestore &restore ); + static TYPEDESCRIPTION m_SaveData[]; + static CSprite *SpriteCreate( const char *pSpriteName, const Vector &origin, BOOL animate ); + +private: + + float m_lastTime; + float m_maxFrame; +}; + + +class CBeam : public CBaseEntity +{ +public: + void Spawn( void ); + void Precache( void ); + int ObjectCaps( void ) + { + int flags = 0; + if ( pev->spawnflags & SF_BEAM_TEMPORARY ) + flags = FCAP_DONT_SAVE; + return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | flags; + } + + void EXPORT TriggerTouch( CBaseEntity *pOther ); + + // These functions are here to show the way beams are encoded as entities. + // Encoding beams as entities simplifies their management in the client/server architecture + inline void SetType( int type ) { pev->rendermode = (pev->rendermode & 0xF0) | (type&0x0F); } + inline void SetFlags( int flags ) { pev->rendermode = (pev->rendermode & 0x0F) | (flags&0xF0); } + inline void SetStartPos( const Vector& pos ) { pev->origin = pos; } + inline void SetEndPos( const Vector& pos ) { pev->angles = pos; } + void SetStartEntity( int entityIndex ); + void SetEndEntity( int entityIndex ); + + inline void SetStartAttachment( int attachment ) { pev->sequence = (pev->sequence & 0x0FFF) | ((attachment&0xF)<<12); } + inline void SetEndAttachment( int attachment ) { pev->skin = (pev->skin & 0x0FFF) | ((attachment&0xF)<<12); } + + inline void SetTexture( int spriteIndex ) { pev->modelindex = spriteIndex; } + inline void SetWidth( int width ) { pev->scale = width; } + inline void SetNoise( int amplitude ) { pev->body = amplitude; } + inline void SetColor( int r, int g, int b ) { pev->rendercolor.x = r; pev->rendercolor.y = g; pev->rendercolor.z = b; } + inline void SetBrightness( int brightness ) { pev->renderamt = brightness; } + inline void SetFrame( float frame ) { pev->frame = frame; } + inline void SetScrollRate( int speed ) { pev->animtime = speed; } + + inline int GetType( void ) { return pev->rendermode & 0x0F; } + inline int GetFlags( void ) { return pev->rendermode & 0xF0; } + inline int GetStartEntity( void ) { return pev->sequence & 0xFFF; } + inline int GetEndEntity( void ) { return pev->skin & 0xFFF; } + + const Vector &GetStartPos( void ); + const Vector &GetEndPos( void ); + + Vector Center( void ) { return (GetStartPos() + GetEndPos()) * 0.5; }; // center point of beam + + inline int GetTexture( void ) { return pev->modelindex; } + inline int GetWidth( void ) { return pev->scale; } + inline int GetNoise( void ) { return pev->body; } + // inline void GetColor( int r, int g, int b ) { pev->rendercolor.x = r; pev->rendercolor.y = g; pev->rendercolor.z = b; } + inline int GetBrightness( void ) { return pev->renderamt; } + inline int GetFrame( void ) { return pev->frame; } + inline int GetScrollRate( void ) { return pev->animtime; } + + // Call after you change start/end positions + void RelinkBeam( void ); +// void SetObjectCollisionBox( void ); + + void DoSparks( const Vector &start, const Vector &end ); + CBaseEntity *RandomTargetname( const char *szName ); + void BeamDamage( TraceResult *ptr ); + // Init after BeamCreate() + void BeamInit( const char *pSpriteName, int width ); + void PointsInit( const Vector &start, const Vector &end ); + void PointEntInit( const Vector &start, int endIndex ); + void EntsInit( int startIndex, int endIndex ); + void HoseInit( const Vector &start, const Vector &direction ); + + static CBeam *BeamCreate( const char *pSpriteName, int width ); + + inline void LiveForTime( float time ) { SetThink(SUB_Remove); pev->nextthink = gpGlobals->time + time; } + inline void BeamDamageInstant( TraceResult *ptr, float damage ) + { + pev->dmg = damage; + pev->dmgtime = gpGlobals->time - 1; + BeamDamage(ptr); + } +}; + + +#define SF_MESSAGE_ONCE 0x0001 // Fade in, not out +#define SF_MESSAGE_ALL 0x0002 // Send to all clients + + +class CLaser : public CBeam +{ +public: + void Spawn( void ); + void Precache( void ); + void KeyValue( KeyValueData *pkvd ); + + void TurnOn( void ); + void TurnOff( void ); + int IsOn( void ); + + void FireAtPoint( TraceResult &point ); + + void EXPORT StrikeThink( void ); + void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + virtual int Save( CSave &save ); + virtual int Restore( CRestore &restore ); + static TYPEDESCRIPTION m_SaveData[]; + + CSprite *m_pSprite; + int m_iszSpriteName; + Vector m_firePosition; +}; + +#endif //EFFECTS_H diff --git a/sdk/hlsdk/dlls/enginecallback.h b/sdk/hlsdk/dlls/enginecallback.h new file mode 100644 index 0000000..953bf5a --- /dev/null +++ b/sdk/hlsdk/dlls/enginecallback.h @@ -0,0 +1,162 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef ENGINECALLBACK_H +#define ENGINECALLBACK_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +#include "event_flags.h" + +// Must be provided by user of this code +extern enginefuncs_t g_engfuncs; + +// The actual engine callbacks +#define GETPLAYERUSERID (*g_engfuncs.pfnGetPlayerUserId) +#define PRECACHE_MODEL (*g_engfuncs.pfnPrecacheModel) +#define PRECACHE_SOUND (*g_engfuncs.pfnPrecacheSound) +#define PRECACHE_GENERIC (*g_engfuncs.pfnPrecacheGeneric) +#define SET_MODEL (*g_engfuncs.pfnSetModel) +#define MODEL_INDEX (*g_engfuncs.pfnModelIndex) +#define MODEL_FRAMES (*g_engfuncs.pfnModelFrames) +#define SET_SIZE (*g_engfuncs.pfnSetSize) +#define CHANGE_LEVEL (*g_engfuncs.pfnChangeLevel) +#define GET_SPAWN_PARMS (*g_engfuncs.pfnGetSpawnParms) +#define SAVE_SPAWN_PARMS (*g_engfuncs.pfnSaveSpawnParms) +#define VEC_TO_YAW (*g_engfuncs.pfnVecToYaw) +#define VEC_TO_ANGLES (*g_engfuncs.pfnVecToAngles) +#define MOVE_TO_ORIGIN (*g_engfuncs.pfnMoveToOrigin) +#define oldCHANGE_YAW (*g_engfuncs.pfnChangeYaw) +#define CHANGE_PITCH (*g_engfuncs.pfnChangePitch) +#define MAKE_VECTORS (*g_engfuncs.pfnMakeVectors) +#define CREATE_ENTITY (*g_engfuncs.pfnCreateEntity) +#define REMOVE_ENTITY (*g_engfuncs.pfnRemoveEntity) +#define CREATE_NAMED_ENTITY (*g_engfuncs.pfnCreateNamedEntity) +#define MAKE_STATIC (*g_engfuncs.pfnMakeStatic) +#define ENT_IS_ON_FLOOR (*g_engfuncs.pfnEntIsOnFloor) +#define DROP_TO_FLOOR (*g_engfuncs.pfnDropToFloor) +#define WALK_MOVE (*g_engfuncs.pfnWalkMove) +#define SET_ORIGIN (*g_engfuncs.pfnSetOrigin) +#define EMIT_SOUND_DYN2 (*g_engfuncs.pfnEmitSound) +#define BUILD_SOUND_MSG (*g_engfuncs.pfnBuildSoundMsg) +#define TRACE_LINE (*g_engfuncs.pfnTraceLine) +#define TRACE_TOSS (*g_engfuncs.pfnTraceToss) +#define TRACE_MONSTER_HULL (*g_engfuncs.pfnTraceMonsterHull) +#define TRACE_HULL (*g_engfuncs.pfnTraceHull) +#define GET_AIM_VECTOR (*g_engfuncs.pfnGetAimVector) +#define SERVER_COMMAND (*g_engfuncs.pfnServerCommand) +#define SERVER_EXECUTE (*g_engfuncs.pfnServerExecute) +#define CLIENT_COMMAND (*g_engfuncs.pfnClientCommand) +#define PARTICLE_EFFECT (*g_engfuncs.pfnParticleEffect) +#define LIGHT_STYLE (*g_engfuncs.pfnLightStyle) +#define DECAL_INDEX (*g_engfuncs.pfnDecalIndex) +#define POINT_CONTENTS (*g_engfuncs.pfnPointContents) +#define CRC32_INIT (*g_engfuncs.pfnCRC32_Init) +#define CRC32_PROCESS_BUFFER (*g_engfuncs.pfnCRC32_ProcessBuffer) +#define CRC32_PROCESS_BYTE (*g_engfuncs.pfnCRC32_ProcessByte) +#define CRC32_FINAL (*g_engfuncs.pfnCRC32_Final) +#define RANDOM_LONG (*g_engfuncs.pfnRandomLong) +#define RANDOM_FLOAT (*g_engfuncs.pfnRandomFloat) +#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId) + +inline void MESSAGE_BEGIN( int msg_dest, int msg_type, const float *pOrigin = NULL, edict_t *ed = NULL ) { + (*g_engfuncs.pfnMessageBegin)(msg_dest, msg_type, pOrigin, ed); +} +#define MESSAGE_END (*g_engfuncs.pfnMessageEnd) +#define WRITE_BYTE (*g_engfuncs.pfnWriteByte) +#define WRITE_CHAR (*g_engfuncs.pfnWriteChar) +#define WRITE_SHORT (*g_engfuncs.pfnWriteShort) +#define WRITE_LONG (*g_engfuncs.pfnWriteLong) +#define WRITE_ANGLE (*g_engfuncs.pfnWriteAngle) +#define WRITE_COORD (*g_engfuncs.pfnWriteCoord) +#define WRITE_STRING (*g_engfuncs.pfnWriteString) +#define WRITE_ENTITY (*g_engfuncs.pfnWriteEntity) +#define CVAR_REGISTER (*g_engfuncs.pfnCVarRegister) +#define CVAR_GET_FLOAT (*g_engfuncs.pfnCVarGetFloat) +#define CVAR_GET_STRING (*g_engfuncs.pfnCVarGetString) +#define CVAR_SET_FLOAT (*g_engfuncs.pfnCVarSetFloat) +#define CVAR_SET_STRING (*g_engfuncs.pfnCVarSetString) +#define CVAR_GET_POINTER (*g_engfuncs.pfnCVarGetPointer) +#define ALERT (*g_engfuncs.pfnAlertMessage) +#define ENGINE_FPRINTF (*g_engfuncs.pfnEngineFprintf) +#define ALLOC_PRIVATE (*g_engfuncs.pfnPvAllocEntPrivateData) +inline void *GET_PRIVATE( edict_t *pent ) +{ + if ( pent ) + return pent->pvPrivateData; + return NULL; +} + +#define FREE_PRIVATE (*g_engfuncs.pfnFreeEntPrivateData) +//#define STRING (*g_engfuncs.pfnSzFromIndex) +#define ALLOC_STRING (*g_engfuncs.pfnAllocString) +#define FIND_ENTITY_BY_STRING (*g_engfuncs.pfnFindEntityByString) +#define GETENTITYILLUM (*g_engfuncs.pfnGetEntityIllum) +#define FIND_ENTITY_IN_SPHERE (*g_engfuncs.pfnFindEntityInSphere) +#define FIND_CLIENT_IN_PVS (*g_engfuncs.pfnFindClientInPVS) +#define EMIT_AMBIENT_SOUND (*g_engfuncs.pfnEmitAmbientSound) +#define GET_MODEL_PTR (*g_engfuncs.pfnGetModelPtr) +#define REG_USER_MSG (*g_engfuncs.pfnRegUserMsg) +#define GET_BONE_POSITION (*g_engfuncs.pfnGetBonePosition) +#define FUNCTION_FROM_NAME (*g_engfuncs.pfnFunctionFromName) +#define NAME_FOR_FUNCTION (*g_engfuncs.pfnNameForFunction) +#define TRACE_TEXTURE (*g_engfuncs.pfnTraceTexture) +#define CLIENT_PRINTF (*g_engfuncs.pfnClientPrintf) +#define CMD_ARGS (*g_engfuncs.pfnCmd_Args) +#define CMD_ARGC (*g_engfuncs.pfnCmd_Argc) +#define CMD_ARGV (*g_engfuncs.pfnCmd_Argv) +#define GET_ATTACHMENT (*g_engfuncs.pfnGetAttachment) +#define SET_VIEW (*g_engfuncs.pfnSetView) +#define SET_CROSSHAIRANGLE (*g_engfuncs.pfnCrosshairAngle) +#define LOAD_FILE_FOR_ME (*g_engfuncs.pfnLoadFileForMe) +#define FREE_FILE (*g_engfuncs.pfnFreeFile) +#define COMPARE_FILE_TIME (*g_engfuncs.pfnCompareFileTime) +#define GET_GAME_DIR (*g_engfuncs.pfnGetGameDir) +#define IS_MAP_VALID (*g_engfuncs.pfnIsMapValid) +#define NUMBER_OF_ENTITIES (*g_engfuncs.pfnNumberOfEntities) +#define IS_DEDICATED_SERVER (*g_engfuncs.pfnIsDedicatedServer) + +#define PRECACHE_EVENT (*g_engfuncs.pfnPrecacheEvent) +#define PLAYBACK_EVENT_FULL (*g_engfuncs.pfnPlaybackEvent) + +#define ENGINE_SET_PVS (*g_engfuncs.pfnSetFatPVS) +#define ENGINE_SET_PAS (*g_engfuncs.pfnSetFatPAS) + +#define ENGINE_CHECK_VISIBILITY (*g_engfuncs.pfnCheckVisibility) + +#define DELTA_SET ( *g_engfuncs.pfnDeltaSetField ) +#define DELTA_UNSET ( *g_engfuncs.pfnDeltaUnsetField ) +#define DELTA_ADDENCODER ( *g_engfuncs.pfnDeltaAddEncoder ) +#define ENGINE_CURRENT_PLAYER ( *g_engfuncs.pfnGetCurrentPlayer ) + +#define ENGINE_CANSKIP ( *g_engfuncs.pfnCanSkipPlayer ) + +#define DELTA_FINDFIELD ( *g_engfuncs.pfnDeltaFindField ) +#define DELTA_SETBYINDEX ( *g_engfuncs.pfnDeltaSetFieldByIndex ) +#define DELTA_UNSETBYINDEX ( *g_engfuncs.pfnDeltaUnsetFieldByIndex ) + +#define ENGINE_GETPHYSINFO ( *g_engfuncs.pfnGetPhysicsInfoString ) + +#define ENGINE_SETGROUPMASK ( *g_engfuncs.pfnSetGroupMask ) + +#define ENGINE_INSTANCE_BASELINE ( *g_engfuncs.pfnCreateInstancedBaseline ) + +#define ENGINE_FORCE_UNMODIFIED ( *g_engfuncs.pfnForceUnmodified ) + +#define PLAYER_CNX_STATS ( *g_engfuncs.pfnGetPlayerStats ) + +#endif //ENGINECALLBACK_H diff --git a/sdk/hlsdk/dlls/explode.h b/sdk/hlsdk/dlls/explode.h new file mode 100644 index 0000000..3feb011 --- /dev/null +++ b/sdk/hlsdk/dlls/explode.h @@ -0,0 +1,32 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef EXPLODE_H +#define EXPLODE_H + + +#define SF_ENVEXPLOSION_NODAMAGE ( 1 << 0 ) // when set, ENV_EXPLOSION will not actually inflict damage +#define SF_ENVEXPLOSION_REPEATABLE ( 1 << 1 ) // can this entity be refired? +#define SF_ENVEXPLOSION_NOFIREBALL ( 1 << 2 ) // don't draw the fireball +#define SF_ENVEXPLOSION_NOSMOKE ( 1 << 3 ) // don't draw the smoke +#define SF_ENVEXPLOSION_NODECAL ( 1 << 4 ) // don't make a scorch mark +#define SF_ENVEXPLOSION_NOSPARKS ( 1 << 5 ) // don't make a scorch mark + +extern DLL_GLOBAL short g_sModelIndexFireball; +extern DLL_GLOBAL short g_sModelIndexSmoke; + + +extern void ExplosionCreate( const Vector ¢er, const Vector &angles, edict_t *pOwner, int magnitude, BOOL doDamage ); + +#endif //EXPLODE_H diff --git a/sdk/hlsdk/dlls/extdll.h b/sdk/hlsdk/dlls/extdll.h new file mode 100644 index 0000000..48c7239 --- /dev/null +++ b/sdk/hlsdk/dlls/extdll.h @@ -0,0 +1,88 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef EXTDLL_H +#define EXTDLL_H + + +// +// Global header file for extension DLLs +// + +// Allow "DEBUG" in addition to default "_DEBUG" +#ifdef _DEBUG +#define DEBUG 1 +#endif + +#ifdef _WIN32 +// Silence certain warnings +#pragma warning(disable : 4244) // int or float down-conversion +#pragma warning(disable : 4305) // int or float data truncation +#pragma warning(disable : 4201) // nameless struct/union +#pragma warning(disable : 4514) // unreferenced inline function removed +#pragma warning(disable : 4100) // unreferenced formal parameter + +// Prevent tons of unused windows definitions +#define WIN32_LEAN_AND_MEAN +#define NOWINRES +#define NOSERVICE +#define NOMCX +#define NOIME +#include "windows.h" +#else // _WIN32 +#define FALSE 0 +#define TRUE (!FALSE) +typedef unsigned long ULONG; +typedef unsigned char BYTE; +typedef int BOOL; +#define MAX_PATH PATH_MAX +#include +#include +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d) +#endif +#endif //_WIN32 + +// Misc C-runtime library headers +#include "stdio.h" +#include "stdlib.h" +#include "math.h" + +// Header file containing definition of globalvars_t and entvars_t +typedef int func_t; // +typedef int string_t; // from engine's pr_comp.h; +typedef float vec_t; // needed before including progdefs.h + +// Vector class +#include "vector.h" + +// Defining it as a (bogus) struct helps enforce type-checking +#define vec3_t Vector + +// Shared engine/DLL constants +#include "const.h" +#include "progdefs.h" +#include "edict.h" + +// Shared header describing protocol between engine and DLLs +#include "eiface.h" + +// Shared header between the client DLL and the game DLLs +#include "cdll_dll.h" + +#endif //EXTDLL_H diff --git a/sdk/hlsdk/dlls/func_break.h b/sdk/hlsdk/dlls/func_break.h new file mode 100644 index 0000000..9bb281d --- /dev/null +++ b/sdk/hlsdk/dlls/func_break.h @@ -0,0 +1,74 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef FUNC_BREAK_H +#define FUNC_BREAK_H + +typedef enum { expRandom, expDirected} Explosions; +typedef enum { matGlass = 0, matWood, matMetal, matFlesh, matCinderBlock, matCeilingTile, matComputer, matUnbreakableGlass, matRocks, matNone, matLastMaterial } Materials; + +#define NUM_SHARDS 6 // this many shards spawned when breakable objects break; + +class CBreakable : public CBaseDelay +{ +public: + // basic functions + void Spawn( void ); + void Precache( void ); + void KeyValue( KeyValueData* pkvd); + void EXPORT BreakTouch( CBaseEntity *pOther ); + void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + void DamageSound( void ); + + // breakables use an overridden takedamage + virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); + // To spark when hit + void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ); + + BOOL IsBreakable( void ); + BOOL SparkWhenHit( void ); + + int DamageDecal( int bitsDamageType ); + + void EXPORT Die( void ); + virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION); } + virtual int Save( CSave &save ); + virtual int Restore( CRestore &restore ); + + inline BOOL Explodable( void ) { return ExplosionMagnitude() > 0; } + inline int ExplosionMagnitude( void ) { return pev->impulse; } + inline void ExplosionSetMagnitude( int magnitude ) { pev->impulse = magnitude; } + + static void MaterialSoundPrecache( Materials precacheMaterial ); + static void MaterialSoundRandom( edict_t *pEdict, Materials soundMaterial, float volume ); + static const char **MaterialSoundList( Materials precacheMaterial, int &soundCount ); + + static const char *pSoundsWood[]; + static const char *pSoundsFlesh[]; + static const char *pSoundsGlass[]; + static const char *pSoundsMetal[]; + static const char *pSoundsConcrete[]; + static const char *pSpawnObjects[]; + + static TYPEDESCRIPTION m_SaveData[]; + + Materials m_Material; + Explosions m_Explosion; + int m_idShard; + float m_angle; + int m_iszGibModel; + int m_iszSpawnObject; +}; + +#endif // FUNC_BREAK_H diff --git a/sdk/hlsdk/dlls/game.h b/sdk/hlsdk/dlls/game.h new file mode 100644 index 0000000..58e7e75 --- /dev/null +++ b/sdk/hlsdk/dlls/game.h @@ -0,0 +1,45 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +#ifndef GAME_H +#define GAME_H + +extern void GameDLLInit( void ); + + +extern cvar_t displaysoundlist; + +// multiplayer server rules +extern cvar_t teamplay; +extern cvar_t fraglimit; +extern cvar_t timelimit; +extern cvar_t friendlyfire; +extern cvar_t falldamage; +extern cvar_t weaponstay; +extern cvar_t forcerespawn; +extern cvar_t flashlight; +extern cvar_t aimcrosshair; +extern cvar_t decalfrequency; +extern cvar_t teamlist; +extern cvar_t teamoverride; +extern cvar_t defaultteam; +extern cvar_t allowmonsters; + +// Engine Cvars +extern cvar_t *g_psv_gravity; +extern cvar_t *g_psv_aim; +extern cvar_t *g_footsteps; + +#endif // GAME_H diff --git a/sdk/hlsdk/dlls/gamerules.h b/sdk/hlsdk/dlls/gamerules.h new file mode 100644 index 0000000..76b3515 --- /dev/null +++ b/sdk/hlsdk/dlls/gamerules.h @@ -0,0 +1,360 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +//========================================================= +// GameRules +//========================================================= + +//#include "weapons.h" +//#include "items.h" +class CBasePlayerItem; +class CBasePlayer; +class CItem; +class CBasePlayerAmmo; + +// weapon respawning return codes +enum +{ + GR_NONE = 0, + + GR_WEAPON_RESPAWN_YES, + GR_WEAPON_RESPAWN_NO, + + GR_AMMO_RESPAWN_YES, + GR_AMMO_RESPAWN_NO, + + GR_ITEM_RESPAWN_YES, + GR_ITEM_RESPAWN_NO, + + GR_PLR_DROP_GUN_ALL, + GR_PLR_DROP_GUN_ACTIVE, + GR_PLR_DROP_GUN_NO, + + GR_PLR_DROP_AMMO_ALL, + GR_PLR_DROP_AMMO_ACTIVE, + GR_PLR_DROP_AMMO_NO, +}; + +// Player relationship return codes +enum +{ + GR_NOTTEAMMATE = 0, + GR_TEAMMATE, + GR_ENEMY, + GR_ALLY, + GR_NEUTRAL, +}; + +class CGameRules +{ +public: + virtual void RefreshSkillData( void );// fill skill data struct with proper values + virtual void Think( void ) = 0;// GR_Think - runs every server frame, should handle any timer tasks, periodic events, etc. + virtual BOOL IsAllowedToSpawn( CBaseEntity *pEntity ) = 0; // Can this item spawn (eg monsters don't spawn in deathmatch). + + virtual BOOL FAllowFlashlight( void ) = 0;// Are players allowed to switch on their flashlight? + virtual BOOL FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) = 0;// should the player switch to this weapon? + virtual BOOL GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) = 0;// I can't use this weapon anymore, get me the next best one. + +// Functions to verify the single/multiplayer status of a game + virtual BOOL IsMultiplayer( void ) = 0;// is this a multiplayer game? (either coop or deathmatch) + virtual BOOL IsDeathmatch( void ) = 0;//is this a deathmatch game? + virtual BOOL IsTeamplay( void ) { return FALSE; };// is this deathmatch game being played with team rules? + virtual BOOL IsCoOp( void ) = 0;// is this a coop game? + virtual const char *GetGameDescription( void ) { return "Half-Life"; } // this is the game name that gets seen in the server browser + +// Client connection/disconnection + virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ) = 0;// a client just connected to the server (player hasn't spawned yet) + virtual void InitHUD( CBasePlayer *pl ) = 0; // the client dll is ready for updating + virtual void ClientDisconnected( edict_t *pClient ) = 0;// a client just disconnected from the server + virtual void UpdateGameMode( CBasePlayer *pPlayer ) {} // the client needs to be informed of the current game mode + +// Client damage rules + virtual float FlPlayerFallDamage( CBasePlayer *pPlayer ) = 0;// this client just hit the ground after a fall. How much damage? + virtual BOOL FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ) {return TRUE;};// can this player take damage from this attacker? + virtual BOOL ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target ) { return TRUE; } + +// Client spawn/respawn control + virtual void PlayerSpawn( CBasePlayer *pPlayer ) = 0;// called by CBasePlayer::Spawn just before releasing player into the game + virtual void PlayerThink( CBasePlayer *pPlayer ) = 0; // called by CBasePlayer::PreThink every frame, before physics are run and after keys are accepted + virtual BOOL FPlayerCanRespawn( CBasePlayer *pPlayer ) = 0;// is this player allowed to respawn now? + virtual float FlPlayerSpawnTime( CBasePlayer *pPlayer ) = 0;// When in the future will this player be able to spawn? + virtual edict_t *GetPlayerSpawnSpot( CBasePlayer *pPlayer );// Place this player on their spawnspot and face them the proper direction. + + virtual BOOL AllowAutoTargetCrosshair( void ) { return TRUE; }; + virtual BOOL ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) { return FALSE; }; // handles the user commands; returns TRUE if command handled properly + virtual void ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ) {} // the player has changed userinfo; can change it now + +// Client kills/scoring + virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ) = 0;// how many points do I award whoever kills this player? + virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) = 0;// Called each time a player dies + virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor )= 0;// Call this from within a GameRules class to report an obituary. +// Weapon retrieval + virtual BOOL CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon );// The player is touching an CBasePlayerItem, do I give it to him? + virtual void PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) = 0;// Called each time a player picks up a weapon from the ground + +// Weapon spawn/respawn control + virtual int WeaponShouldRespawn( CBasePlayerItem *pWeapon ) = 0;// should this weapon respawn? + virtual float FlWeaponRespawnTime( CBasePlayerItem *pWeapon ) = 0;// when may this weapon respawn? + virtual float FlWeaponTryRespawn( CBasePlayerItem *pWeapon ) = 0; // can i respawn now, and if not, when should i try again? + virtual Vector VecWeaponRespawnSpot( CBasePlayerItem *pWeapon ) = 0;// where in the world should this weapon respawn? + +// Item retrieval + virtual BOOL CanHaveItem( CBasePlayer *pPlayer, CItem *pItem ) = 0;// is this player allowed to take this item? + virtual void PlayerGotItem( CBasePlayer *pPlayer, CItem *pItem ) = 0;// call each time a player picks up an item (battery, healthkit, longjump) + +// Item spawn/respawn control + virtual int ItemShouldRespawn( CItem *pItem ) = 0;// Should this item respawn? + virtual float FlItemRespawnTime( CItem *pItem ) = 0;// when may this item respawn? + virtual Vector VecItemRespawnSpot( CItem *pItem ) = 0;// where in the world should this item respawn? + +// Ammo retrieval + virtual BOOL CanHaveAmmo( CBasePlayer *pPlayer, const char *pszAmmoName, int iMaxCarry );// can this player take more of this ammo? + virtual void PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int iCount ) = 0;// called each time a player picks up some ammo in the world + +// Ammo spawn/respawn control + virtual int AmmoShouldRespawn( CBasePlayerAmmo *pAmmo ) = 0;// should this ammo item respawn? + virtual float FlAmmoRespawnTime( CBasePlayerAmmo *pAmmo ) = 0;// when should this ammo item respawn? + virtual Vector VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo ) = 0;// where in the world should this ammo item respawn? + // by default, everything spawns + +// Healthcharger respawn control + virtual float FlHealthChargerRechargeTime( void ) = 0;// how long until a depleted HealthCharger recharges itself? + virtual float FlHEVChargerRechargeTime( void ) { return 0; }// how long until a depleted HealthCharger recharges itself? + +// What happens to a dead player's weapons + virtual int DeadPlayerWeapons( CBasePlayer *pPlayer ) = 0;// what do I do with a player's weapons when he's killed? + +// What happens to a dead player's ammo + virtual int DeadPlayerAmmo( CBasePlayer *pPlayer ) = 0;// Do I drop ammo when the player dies? How much? + +// Teamplay stuff + virtual const char *GetTeamID( CBaseEntity *pEntity ) = 0;// what team is this entity on? + virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ) = 0;// What is the player's relationship with this entity? + virtual int GetTeamIndex( const char *pTeamName ) { return -1; } + virtual const char *GetIndexedTeamName( int teamIndex ) { return ""; } + virtual BOOL IsValidTeam( const char *pTeamName ) { return TRUE; } + virtual void ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib ) {} + virtual const char *SetDefaultPlayerTeam( CBasePlayer *pPlayer ) { return ""; } + +// Sounds + virtual BOOL PlayTextureSounds( void ) { return TRUE; } + virtual BOOL PlayFootstepSounds( CBasePlayer *pl, float fvol ) { return TRUE; } + +// Monsters + virtual BOOL FAllowMonsters( void ) = 0;//are monsters allowed + + // Immediately end a multiplayer game + virtual void EndMultiplayerGame( void ) {} +}; + +extern CGameRules *InstallGameRules( void ); + + +//========================================================= +// CHalfLifeRules - rules for the single player Half-Life +// game. +//========================================================= +class CHalfLifeRules : public CGameRules +{ +public: + CHalfLifeRules ( void ); + +// GR_Think + virtual void Think( void ); + virtual BOOL IsAllowedToSpawn( CBaseEntity *pEntity ); + virtual BOOL FAllowFlashlight( void ) { return TRUE; }; + + virtual BOOL FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ); + virtual BOOL GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ); + +// Functions to verify the single/multiplayer status of a game + virtual BOOL IsMultiplayer( void ); + virtual BOOL IsDeathmatch( void ); + virtual BOOL IsCoOp( void ); + +// Client connection/disconnection + virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); + virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating + virtual void ClientDisconnected( edict_t *pClient ); + +// Client damage rules + virtual float FlPlayerFallDamage( CBasePlayer *pPlayer ); + +// Client spawn/respawn control + virtual void PlayerSpawn( CBasePlayer *pPlayer ); + virtual void PlayerThink( CBasePlayer *pPlayer ); + virtual BOOL FPlayerCanRespawn( CBasePlayer *pPlayer ); + virtual float FlPlayerSpawnTime( CBasePlayer *pPlayer ); + + virtual BOOL AllowAutoTargetCrosshair( void ); + +// Client kills/scoring + virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ); + virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); + virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); + +// Weapon retrieval + virtual void PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ); + +// Weapon spawn/respawn control + virtual int WeaponShouldRespawn( CBasePlayerItem *pWeapon ); + virtual float FlWeaponRespawnTime( CBasePlayerItem *pWeapon ); + virtual float FlWeaponTryRespawn( CBasePlayerItem *pWeapon ); + virtual Vector VecWeaponRespawnSpot( CBasePlayerItem *pWeapon ); + +// Item retrieval + virtual BOOL CanHaveItem( CBasePlayer *pPlayer, CItem *pItem ); + virtual void PlayerGotItem( CBasePlayer *pPlayer, CItem *pItem ); + +// Item spawn/respawn control + virtual int ItemShouldRespawn( CItem *pItem ); + virtual float FlItemRespawnTime( CItem *pItem ); + virtual Vector VecItemRespawnSpot( CItem *pItem ); + +// Ammo retrieval + virtual void PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int iCount ); + +// Ammo spawn/respawn control + virtual int AmmoShouldRespawn( CBasePlayerAmmo *pAmmo ); + virtual float FlAmmoRespawnTime( CBasePlayerAmmo *pAmmo ); + virtual Vector VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo ); + +// Healthcharger respawn control + virtual float FlHealthChargerRechargeTime( void ); + +// What happens to a dead player's weapons + virtual int DeadPlayerWeapons( CBasePlayer *pPlayer ); + +// What happens to a dead player's ammo + virtual int DeadPlayerAmmo( CBasePlayer *pPlayer ); + +// Monsters + virtual BOOL FAllowMonsters( void ); + +// Teamplay stuff + virtual const char *GetTeamID( CBaseEntity *pEntity ) {return "";}; + virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ); +}; + +//========================================================= +// CHalfLifeMultiplay - rules for the basic half life multiplayer +// competition +//========================================================= +class CHalfLifeMultiplay : public CGameRules +{ +public: + CHalfLifeMultiplay(); + +// GR_Think + virtual void Think( void ); + virtual void RefreshSkillData( void ); + virtual BOOL IsAllowedToSpawn( CBaseEntity *pEntity ); + virtual BOOL FAllowFlashlight( void ); + + virtual BOOL FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ); + virtual BOOL GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ); + +// Functions to verify the single/multiplayer status of a game + virtual BOOL IsMultiplayer( void ); + virtual BOOL IsDeathmatch( void ); + virtual BOOL IsCoOp( void ); + +// Client connection/disconnection + // If ClientConnected returns FALSE, the connection is rejected and the user is provided the reason specified in + // svRejectReason + // Only the client's name and remote address are provided to the dll for verification. + virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); + virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating + virtual void ClientDisconnected( edict_t *pClient ); + virtual void UpdateGameMode( CBasePlayer *pPlayer ); // the client needs to be informed of the current game mode + +// Client damage rules + virtual float FlPlayerFallDamage( CBasePlayer *pPlayer ); + virtual BOOL FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ); + +// Client spawn/respawn control + virtual void PlayerSpawn( CBasePlayer *pPlayer ); + virtual void PlayerThink( CBasePlayer *pPlayer ); + virtual BOOL FPlayerCanRespawn( CBasePlayer *pPlayer ); + virtual float FlPlayerSpawnTime( CBasePlayer *pPlayer ); + virtual edict_t *GetPlayerSpawnSpot( CBasePlayer *pPlayer ); + + virtual BOOL AllowAutoTargetCrosshair( void ); + virtual BOOL ClientCommand( CBasePlayer *pPlayer, const char *pcmd ); + +// Client kills/scoring + virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ); + virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); + virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); + +// Weapon retrieval + virtual void PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ); + virtual BOOL CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon );// The player is touching an CBasePlayerItem, do I give it to him? + +// Weapon spawn/respawn control + virtual int WeaponShouldRespawn( CBasePlayerItem *pWeapon ); + virtual float FlWeaponRespawnTime( CBasePlayerItem *pWeapon ); + virtual float FlWeaponTryRespawn( CBasePlayerItem *pWeapon ); + virtual Vector VecWeaponRespawnSpot( CBasePlayerItem *pWeapon ); + +// Item retrieval + virtual BOOL CanHaveItem( CBasePlayer *pPlayer, CItem *pItem ); + virtual void PlayerGotItem( CBasePlayer *pPlayer, CItem *pItem ); + +// Item spawn/respawn control + virtual int ItemShouldRespawn( CItem *pItem ); + virtual float FlItemRespawnTime( CItem *pItem ); + virtual Vector VecItemRespawnSpot( CItem *pItem ); + +// Ammo retrieval + virtual void PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int iCount ); + +// Ammo spawn/respawn control + virtual int AmmoShouldRespawn( CBasePlayerAmmo *pAmmo ); + virtual float FlAmmoRespawnTime( CBasePlayerAmmo *pAmmo ); + virtual Vector VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo ); + +// Healthcharger respawn control + virtual float FlHealthChargerRechargeTime( void ); + virtual float FlHEVChargerRechargeTime( void ); + +// What happens to a dead player's weapons + virtual int DeadPlayerWeapons( CBasePlayer *pPlayer ); + +// What happens to a dead player's ammo + virtual int DeadPlayerAmmo( CBasePlayer *pPlayer ); + +// Teamplay stuff + virtual const char *GetTeamID( CBaseEntity *pEntity ) {return "";} + virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ); + + virtual BOOL PlayTextureSounds( void ) { return FALSE; } + virtual BOOL PlayFootstepSounds( CBasePlayer *pl, float fvol ); + +// Monsters + virtual BOOL FAllowMonsters( void ); + + // Immediately end a multiplayer game + virtual void EndMultiplayerGame( void ) { GoToIntermission(); } + +protected: + virtual void ChangeLevel( void ); + virtual void GoToIntermission( void ); + float m_flIntermissionEndTime; + BOOL m_iEndIntermissionButtonHit; + void SendMOTDToClient( edict_t *client ); +}; + +extern DLL_GLOBAL CGameRules* g_pGameRules; diff --git a/sdk/hlsdk/dlls/hornet.h b/sdk/hlsdk/dlls/hornet.h new file mode 100644 index 0000000..98d1710 --- /dev/null +++ b/sdk/hlsdk/dlls/hornet.h @@ -0,0 +1,58 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +//========================================================= +// Hornets +//========================================================= + +//========================================================= +// Hornet Defines +//========================================================= +#define HORNET_TYPE_RED 0 +#define HORNET_TYPE_ORANGE 1 +#define HORNET_RED_SPEED (float)600 +#define HORNET_ORANGE_SPEED (float)800 +#define HORNET_BUZZ_VOLUME (float)0.8 + +extern int iHornetPuff; + +//========================================================= +// Hornet - this is the projectile that the Alien Grunt fires. +//========================================================= +class CHornet : public CBaseMonster +{ +public: + void Spawn( void ); + void Precache( void ); + int Classify ( void ); + int IRelationship ( CBaseEntity *pTarget ); + virtual int Save( CSave &save ); + virtual int Restore( CRestore &restore ); + static TYPEDESCRIPTION m_SaveData[]; + + void IgniteTrail( void ); + void EXPORT StartTrack ( void ); + void EXPORT StartDart ( void ); + void EXPORT TrackTarget ( void ); + void EXPORT TrackTouch ( CBaseEntity *pOther ); + void EXPORT DartTouch( CBaseEntity *pOther ); + void EXPORT DieTouch ( CBaseEntity *pOther ); + + int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ); + + float m_flStopAttack; + int m_iHornetType; + float m_flFlySpeed; +}; + diff --git a/sdk/hlsdk/dlls/items.h b/sdk/hlsdk/dlls/items.h new file mode 100644 index 0000000..e985296 --- /dev/null +++ b/sdk/hlsdk/dlls/items.h @@ -0,0 +1,29 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef ITEMS_H +#define ITEMS_H + + +class CItem : public CBaseEntity +{ +public: + void Spawn( void ); + CBaseEntity* Respawn( void ); + void EXPORT ItemTouch( CBaseEntity *pOther ); + void EXPORT Materialize( void ); + virtual BOOL MyTouch( CBasePlayer *pPlayer ) { return FALSE; }; +}; + +#endif // ITEMS_H diff --git a/sdk/hlsdk/dlls/maprules.h b/sdk/hlsdk/dlls/maprules.h new file mode 100644 index 0000000..57f9939 --- /dev/null +++ b/sdk/hlsdk/dlls/maprules.h @@ -0,0 +1,22 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +#ifndef MAPRULES_H +#define MAPRULES_H + + + +#endif // MAPRULES_H + diff --git a/sdk/hlsdk/dlls/monsterevent.h b/sdk/hlsdk/dlls/monsterevent.h new file mode 100644 index 0000000..46c5624 --- /dev/null +++ b/sdk/hlsdk/dlls/monsterevent.h @@ -0,0 +1,34 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef MONSTEREVENT_H +#define MONSTEREVENT_H + +typedef struct +{ + int event; + char *options; +} MonsterEvent_t; + +#define EVENT_SPECIFIC 0 +#define EVENT_SCRIPTED 1000 +#define EVENT_SHARED 2000 +#define EVENT_CLIENT 5000 + +#define MONSTER_EVENT_BODYDROP_LIGHT 2001 +#define MONSTER_EVENT_BODYDROP_HEAVY 2002 + +#define MONSTER_EVENT_SWISHSOUND 2010 + +#endif // MONSTEREVENT_H diff --git a/sdk/hlsdk/dlls/monsters.h b/sdk/hlsdk/dlls/monsters.h new file mode 100644 index 0000000..a0a8da6 --- /dev/null +++ b/sdk/hlsdk/dlls/monsters.h @@ -0,0 +1,88 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef MONSTERS_H +#include "skill.h" +#define MONSTERS_H + +/* + +===== monsters.h ======================================================== + + Header file for monster-related utility code + +*/ + +// Hit Group standards +#define HITGROUP_GENERIC 0 +#define HITGROUP_HEAD 1 +#define HITGROUP_CHEST 2 +#define HITGROUP_STOMACH 3 +#define HITGROUP_LEFTARM 4 +#define HITGROUP_RIGHTARM 5 +#define HITGROUP_LEFTLEG 6 +#define HITGROUP_RIGHTLEG 7 + + +// spawn flags 256 and above are already taken by the engine +extern void UTIL_MoveToOrigin( edict_t* pent, const Vector &vecGoal, float flDist, int iMoveType ); + +Vector VecCheckToss ( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flGravityAdj = 1.0 ); +Vector VecCheckThrow ( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flSpeed, float flGravityAdj = 1.0 ); +extern DLL_GLOBAL Vector g_vecAttackDir; +extern DLL_GLOBAL CONSTANT float g_flMeleeRange; +extern DLL_GLOBAL CONSTANT float g_flMediumRange; +extern DLL_GLOBAL CONSTANT float g_flLongRange; +extern void EjectBrass (const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype ); +extern void ExplodeModel( const Vector &vecOrigin, float speed, int model, int count ); + +BOOL FBoxVisible ( entvars_t *pevLooker, entvars_t *pevTarget ); +BOOL FBoxVisible ( entvars_t *pevLooker, entvars_t *pevTarget, Vector &vecTargetOrigin, float flSize = 0.0 ); + +// monster to monster relationship types +#define R_AL -2 // (ALLY) pals. Good alternative to R_NO when applicable. +#define R_FR -1// (FEAR)will run +#define R_NO 0// (NO RELATIONSHIP) disregard +#define R_DL 1// (DISLIKE) will attack +#define R_HT 2// (HATE)will attack this character instead of any visible DISLIKEd characters +#define R_NM 3// (NEMESIS) A monster Will ALWAYS attack its nemsis, no matter what + + +#define bits_MEMORY_KILLED ( 1 << 7 )// HACKHACK -- remember that I've already called my Killed() + +// +// A gib is a chunk of a body, or a piece of wood/metal/rocks/etc. +// +class CGib : public CBaseEntity +{ +public: + void Spawn( const char *szGibModel ); + void EXPORT BounceGibTouch ( CBaseEntity *pOther ); + void EXPORT StickyGibTouch ( CBaseEntity *pOther ); + void EXPORT WaitTillLand( void ); + void LimitVelocity( void ); + + virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DONT_SAVE; } + static void SpawnHeadGib( entvars_t *pevVictim ); + static void SpawnRandomGibs( entvars_t *pevVictim, int cGibs, int human ); + static void SpawnStickyGibs( entvars_t *pevVictim, Vector vecOrigin, int cGibs ); + + int m_bloodColor; + int m_cBloodDecals; + int m_material; + float m_lifeTime; +}; + + +#endif //MONSTERS_H diff --git a/sdk/hlsdk/dlls/nodes.h b/sdk/hlsdk/dlls/nodes.h new file mode 100644 index 0000000..b1a5d13 --- /dev/null +++ b/sdk/hlsdk/dlls/nodes.h @@ -0,0 +1,54 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +//========================================================= +// nodes.h +//========================================================= + +#ifndef NODES_H +#define NODES_H + +#define bits_NODE_GROUP_REALM 1 + +class CLink +{ +public: + entvars_t *m_pLinkEnt;// the entity that blocks this connection (doors, etc) +}; + + +class CGraph +{ +public: + BOOL m_fGraphPresent;// is the graph in memory? + BOOL m_fGraphPointersSet;// are the entity pointers for the graph all set? + + int m_cLinks;// total number of links + CLink *m_pLinkPool;// big list of all node connections + + void InitGraph( void ); + int AllocNodes ( void ); + + int CheckNODFile(char *szMapName); + int FLoadGraph(char *szMapName); + int FSetGraphPointers(void); + void ShowNodeConnections ( int iNode ); + int FindNearestNode ( const Vector &vecOrigin, CBaseEntity *pEntity ); + int FindNearestNode ( const Vector &vecOrigin, int afNodeTypes ); + +}; + +extern CGraph WorldGraph; + +#endif // NODES_H \ No newline at end of file diff --git a/sdk/hlsdk/dlls/plane.h b/sdk/hlsdk/dlls/plane.h new file mode 100644 index 0000000..af70f1c --- /dev/null +++ b/sdk/hlsdk/dlls/plane.h @@ -0,0 +1,43 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef PLANE_H +#define PLANE_H + +//========================================================= +// Plane +//========================================================= +class CPlane +{ +public: + CPlane ( void ); + + //========================================================= + // InitializePlane - Takes a normal for the plane and a + // point on the plane and + //========================================================= + void InitializePlane ( const Vector &vecNormal, const Vector &vecPoint ); + + //========================================================= + // PointInFront - determines whether the given vector is + // in front of the plane. + //========================================================= + BOOL PointInFront ( const Vector &vecPoint ); + + Vector m_vecNormal; + float m_flDist; + BOOL m_fInitialized; +}; + +#endif // PLANE_H diff --git a/sdk/hlsdk/dlls/player.h b/sdk/hlsdk/dlls/player.h new file mode 100644 index 0000000..439058f --- /dev/null +++ b/sdk/hlsdk/dlls/player.h @@ -0,0 +1,324 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef PLAYER_H +#define PLAYER_H + + +#include "pm_materials.h" + + +#define PLAYER_FATAL_FALL_SPEED 1024// approx 60 feet +#define PLAYER_MAX_SAFE_FALL_SPEED 580// approx 20 feet +#define DAMAGE_FOR_FALL_SPEED (float) 100 / ( PLAYER_FATAL_FALL_SPEED - PLAYER_MAX_SAFE_FALL_SPEED )// damage per unit per second. +#define PLAYER_MIN_BOUNCE_SPEED 200 +#define PLAYER_FALL_PUNCH_THRESHHOLD (float)350 // won't punch player's screen/make scrape noise unless player falling at least this fast. + +// +// Player PHYSICS FLAGS bits +// +#define PFLAG_ONLADDER ( 1<<0 ) +#define PFLAG_ONSWING ( 1<<0 ) +#define PFLAG_ONTRAIN ( 1<<1 ) +#define PFLAG_ONBARNACLE ( 1<<2 ) +#define PFLAG_DUCKING ( 1<<3 ) // In the process of ducking, but totally squatted yet +#define PFLAG_USING ( 1<<4 ) // Using a continuous entity +#define PFLAG_OBSERVER ( 1<<5 ) // player is locked in stationary cam mode. Spectators can move, observers can't. + +// +// generic player +// +//----------------------------------------------------- +//This is Half-Life player entity +//----------------------------------------------------- +#define CSUITPLAYLIST 4 // max of 4 suit sentences queued up at any time + +#define SUIT_GROUP TRUE +#define SUIT_SENTENCE FALSE + +#define SUIT_REPEAT_OK 0 +#define SUIT_NEXT_IN_30SEC 30 +#define SUIT_NEXT_IN_1MIN 60 +#define SUIT_NEXT_IN_5MIN 300 +#define SUIT_NEXT_IN_10MIN 600 +#define SUIT_NEXT_IN_30MIN 1800 +#define SUIT_NEXT_IN_1HOUR 3600 + +#define CSUITNOREPEAT 32 + +#define SOUND_FLASHLIGHT_ON "items/flashlight1.wav" +#define SOUND_FLASHLIGHT_OFF "items/flashlight1.wav" + +#define TEAM_NAME_LENGTH 16 + +typedef enum +{ + PLAYER_IDLE, + PLAYER_WALK, + PLAYER_JUMP, + PLAYER_SUPERJUMP, + PLAYER_DIE, + PLAYER_ATTACK1, +} PLAYER_ANIM; + +#define MAX_ID_RANGE 2048 +#define SBAR_STRING_SIZE 128 + +enum sbar_data +{ + SBAR_ID_TARGETNAME = 1, + SBAR_ID_TARGETHEALTH, + SBAR_ID_TARGETARMOR, + SBAR_END, +}; + +#define CHAT_INTERVAL 1.0f + +class CBasePlayer : public CBaseMonster +{ +public: + int random_seed; // See that is shared between client & server for shared weapons code + + int m_iPlayerSound;// the index of the sound list slot reserved for this player + int m_iTargetVolume;// ideal sound volume. + int m_iWeaponVolume;// how loud the player's weapon is right now. + int m_iExtraSoundTypes;// additional classification for this weapon's sound + int m_iWeaponFlash;// brightness of the weapon flash + float m_flStopExtraSoundTime; + + float m_flFlashLightTime; // Time until next battery draw/Recharge + int m_iFlashBattery; // Flashlight Battery Draw + + int m_afButtonLast; + int m_afButtonPressed; + int m_afButtonReleased; + + edict_t *m_pentSndLast; // last sound entity to modify player room type + float m_flSndRoomtype; // last roomtype set by sound entity + float m_flSndRange; // dist from player to sound entity + + float m_flFallVelocity; + + int m_rgItems[MAX_ITEMS]; + int m_fKnownItem; // True when a new item needs to be added + int m_fNewAmmo; // True when a new item has been added + + unsigned int m_afPhysicsFlags; // physics flags - set when 'normal' physics should be revisited or overriden + float m_fNextSuicideTime; // the time after which the player can next use the suicide command + + +// these are time-sensitive things that we keep track of + float m_flTimeStepSound; // when the last stepping sound was made + float m_flTimeWeaponIdle; // when to play another weapon idle animation. + float m_flSwimTime; // how long player has been underwater + float m_flDuckTime; // how long we've been ducking + float m_flWallJumpTime; // how long until next walljump + + float m_flSuitUpdate; // when to play next suit update + int m_rgSuitPlayList[CSUITPLAYLIST];// next sentencenum to play for suit update + int m_iSuitPlayNext; // next sentence slot for queue storage; + int m_rgiSuitNoRepeat[CSUITNOREPEAT]; // suit sentence no repeat list + float m_rgflSuitNoRepeatTime[CSUITNOREPEAT]; // how long to wait before allowing repeat + int m_lastDamageAmount; // Last damage taken + float m_tbdPrev; // Time-based damage timer + + float m_flgeigerRange; // range to nearest radiation source + float m_flgeigerDelay; // delay per update of range msg to client + int m_igeigerRangePrev; + int m_iStepLeft; // alternate left/right foot stepping sound + char m_szTextureName[CBTEXTURENAMEMAX]; // current texture name we're standing on + char m_chTextureType; // current texture type + + int m_idrowndmg; // track drowning damage taken + int m_idrownrestored; // track drowning damage restored + + int m_bitsHUDDamage; // Damage bits for the current fame. These get sent to + // the hude via the DAMAGE message + BOOL m_fInitHUD; // True when deferred HUD restart msg needs to be sent + BOOL m_fGameHUDInitialized; + int m_iTrain; // Train control position + BOOL m_fWeapon; // Set this to FALSE to force a reset of the current weapon HUD info + + EHANDLE m_pTank; // the tank which the player is currently controlling, NULL if no tank + float m_fDeadTime; // the time at which the player died (used in PlayerDeathThink()) + + BOOL m_fNoPlayerSound; // a debugging feature. Player makes no sound if this is true. + BOOL m_fLongJump; // does this player have the longjump module? + + float m_tSneaking; + int m_iUpdateTime; // stores the number of frame ticks before sending HUD update messages + int m_iClientHealth; // the health currently known by the client. If this changes, send a new + int m_iClientBattery; // the Battery currently known by the client. If this changes, send a new + int m_iHideHUD; // the players hud weapon info is to be hidden + int m_iClientHideHUD; + int m_iFOV; // field of view + int m_iClientFOV; // client's known FOV + // usable player items + CBasePlayerItem *m_rgpPlayerItems[MAX_ITEM_TYPES]; + CBasePlayerItem *m_pActiveItem; + CBasePlayerItem *m_pClientActiveItem; // client version of the active item + CBasePlayerItem *m_pLastItem; + // shared ammo slots + int m_rgAmmo[MAX_AMMO_SLOTS]; + int m_rgAmmoLast[MAX_AMMO_SLOTS]; + + Vector m_vecAutoAim; + BOOL m_fOnTarget; + int m_iDeaths; + float m_iRespawnFrames; // used in PlayerDeathThink() to make sure players can always respawn + + int m_lastx, m_lasty; // These are the previous update's crosshair angles, DON"T SAVE/RESTORE + + int m_nCustomSprayFrames;// Custom clan logo frames for this player + float m_flNextDecalTime;// next time this player can spray a decal + + char m_szTeamName[TEAM_NAME_LENGTH]; + + virtual void Spawn( void ); + void Pain( void ); + +// virtual void Think( void ); + virtual void Jump( void ); + virtual void Duck( void ); + virtual void PreThink( void ); + virtual void PostThink( void ); + virtual Vector GetGunPosition( void ); + virtual int TakeHealth( float flHealth, int bitsDamageType ); + virtual void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType); + virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType); + virtual void Killed( entvars_t *pevAttacker, int iGib ); + virtual Vector BodyTarget( const Vector &posSrc ) { return Center( ) + pev->view_ofs * RANDOM_FLOAT( 0.5, 1.1 ); }; // position to shoot at + virtual void StartSneaking( void ) { m_tSneaking = gpGlobals->time - 1; } + virtual void StopSneaking( void ) { m_tSneaking = gpGlobals->time + 30; } + virtual BOOL IsSneaking( void ) { return m_tSneaking <= gpGlobals->time; } + virtual BOOL IsAlive( void ) { return (pev->deadflag == DEAD_NO) && pev->health > 0; } + virtual BOOL ShouldFadeOnDeath( void ) { return FALSE; } + virtual BOOL IsPlayer( void ) { return TRUE; } // Spectators should return FALSE for this, they aren't "players" as far as game logic is concerned + + virtual BOOL IsNetClient( void ) { return TRUE; } // Bots should return FALSE for this, they can't receive NET messages + // Spectators should return TRUE for this + virtual const char *TeamID( void ); + + virtual int Save( CSave &save ); + virtual int Restore( CRestore &restore ); + void RenewItems(void); + void PackDeadPlayerItems( void ); + void RemoveAllItems( BOOL removeSuit ); + BOOL SwitchWeapon( CBasePlayerItem *pWeapon ); + + // JOHN: sends custom messages if player HUD data has changed (eg health, ammo) + virtual void UpdateClientData( void ); + + static TYPEDESCRIPTION m_playerSaveData[]; + + // Player is moved across the transition by other means + virtual int ObjectCaps( void ) { return CBaseMonster :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } + virtual void Precache( void ); + BOOL IsOnLadder( void ); + BOOL FlashlightIsOn( void ); + void FlashlightTurnOn( void ); + void FlashlightTurnOff( void ); + + void UpdatePlayerSound ( void ); + void DeathSound ( void ); + + int Classify ( void ); + void SetAnimation( PLAYER_ANIM playerAnim ); + void SetWeaponAnimType( const char *szExtention ); + char m_szAnimExtention[32]; + + // custom player functions + virtual void ImpulseCommands( void ); + void CheatImpulseCommands( int iImpulse ); + + void StartDeathCam( void ); + void StartObserver( Vector vecPosition, Vector vecViewAngle ); + + void AddPoints( int score, BOOL bAllowNegativeScore ); + void AddPointsToTeam( int score, BOOL bAllowNegativeScore ); + BOOL AddPlayerItem( CBasePlayerItem *pItem ); + BOOL RemovePlayerItem( CBasePlayerItem *pItem ); + void DropPlayerItem ( char *pszItemName ); + BOOL HasPlayerItem( CBasePlayerItem *pCheckItem ); + BOOL HasNamedPlayerItem( const char *pszItemName ); + BOOL HasWeapons( void );// do I have ANY weapons? + void SelectPrevItem( int iItem ); + void SelectNextItem( int iItem ); + void SelectLastItem(void); + void SelectItem(const char *pstr); + void ItemPreFrame( void ); + void ItemPostFrame( void ); + void GiveNamedItem( const char *szName ); + void EnableControl(BOOL fControl); + + int GiveAmmo( int iAmount, char *szName, int iMax ); + void SendAmmoUpdate(void); + + void WaterMove( void ); + void EXPORT PlayerDeathThink( void ); + void PlayerUse( void ); + + void CheckSuitUpdate(); + void SetSuitUpdate(char *name, int fgroup, int iNoRepeat); + void UpdateGeigerCounter( void ); + void CheckTimeBasedDamage( void ); + + BOOL FBecomeProne ( void ); + void BarnacleVictimBitten ( entvars_t *pevBarnacle ); + void BarnacleVictimReleased ( void ); + static int GetAmmoIndex(const char *psz); + int AmmoInventory( int iAmmoIndex ); + int Illumination( void ); + + void ResetAutoaim( void ); + Vector GetAutoaimVector( float flDelta ); + Vector AutoaimDeflection( Vector &vecSrc, float flDist, float flDelta ); + + void ForceClientDllUpdate( void ); // Forces all client .dll specific data to be resent to client. + + void DeathMessage( entvars_t *pevKiller ); + + void SetCustomDecalFrames( int nFrames ); + int GetCustomDecalFrames( void ); + + void CBasePlayer::TabulateAmmo( void ); + + float m_flStartCharge; + float m_flAmmoStartCharge; + float m_flPlayAftershock; + float m_flNextAmmoBurn;// while charging, when to absorb another unit of player's ammo? + + //Player ID + void InitStatusBar( void ); + void UpdateStatusBar( void ); + int m_izSBarState[ SBAR_END ]; + float m_flNextSBarUpdateTime; + float m_flStatusBarDisappearDelay; + char m_SbarString0[ SBAR_STRING_SIZE ]; + char m_SbarString1[ SBAR_STRING_SIZE ]; + + float m_flNextChatTime; + +}; + +#define AUTOAIM_2DEGREES 0.0348994967025 +#define AUTOAIM_5DEGREES 0.08715574274766 +#define AUTOAIM_8DEGREES 0.1391731009601 +#define AUTOAIM_10DEGREES 0.1736481776669 + + +extern int gmsgHudText; +extern BOOL gInitHUD; + +#endif // PLAYER_H diff --git a/sdk/hlsdk/dlls/saverestore.h b/sdk/hlsdk/dlls/saverestore.h new file mode 100644 index 0000000..f1cd418 --- /dev/null +++ b/sdk/hlsdk/dlls/saverestore.h @@ -0,0 +1,176 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// Implementation in UTIL.CPP +#ifndef SAVERESTORE_H +#define SAVERESTORE_H + +class CBaseEntity; + +class CSaveRestoreBuffer +{ +public: + CSaveRestoreBuffer( void ); + CSaveRestoreBuffer( SAVERESTOREDATA *pdata ); + virtual ~CSaveRestoreBuffer( void ); + + int EntityIndex( entvars_t *pevLookup ); + int EntityIndex( edict_t *pentLookup ); + int EntityIndex( EOFFSET eoLookup ); + int EntityIndex( CBaseEntity *pEntity ); + + int EntityFlags( int entityIndex, int flags ) { return EntityFlagsSet( entityIndex, 0 ); } + int EntityFlagsSet( int entityIndex, int flags ); + + edict_t *EntityFromIndex( int entityIndex ); + + unsigned short TokenHash( const char *pszToken ); + +protected: + SAVERESTOREDATA *m_pdata; + void BufferRewind( int size ); + unsigned int HashString( const char *pszToken ); +private: + // effc++ rule 11 + void operator=(CSaveRestoreBuffer&); + CSaveRestoreBuffer(const CSaveRestoreBuffer&); +}; + + +class CSave : public CSaveRestoreBuffer +{ +public: + CSave( SAVERESTOREDATA *pdata ) : CSaveRestoreBuffer( pdata ) {}; + + void WriteShort( const char *pname, const short *value, int count ); + void WriteInt( const char *pname, const int *value, int count ); // Save an int + void WriteFloat( const char *pname, const float *value, int count ); // Save a float + void WriteTime( const char *pname, const float *value, int count ); // Save a float (timevalue) + void WriteData( const char *pname, int size, const char *pdata ); // Save a binary data block + void WriteString( const char *pname, const char *pstring ); // Save a null-terminated string + void WriteString( const char *pname, const int *stringId, int count ); // Save a null-terminated string (engine string) + void WriteVector( const char *pname, const Vector &value ); // Save a vector + void WriteVector( const char *pname, const float *value, int count ); // Save a vector + void WritePositionVector( const char *pname, const Vector &value ); // Offset for landmark if necessary + void WritePositionVector( const char *pname, const float *value, int count ); // array of pos vectors + void WriteFunction( const char *pname, const int *value, int count ); // Save a function pointer + int WriteEntVars( const char *pname, entvars_t *pev ); // Save entvars_t (entvars_t) + int WriteFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); + +private: + int DataEmpty( const char *pdata, int size ); + void BufferField( const char *pname, int size, const char *pdata ); + void BufferString( char *pdata, int len ); + void BufferData( const char *pdata, int size ); + void BufferHeader( const char *pname, int size ); +}; + +typedef struct +{ + unsigned short size; + unsigned short token; + char *pData; +} HEADER; + +class CRestore : public CSaveRestoreBuffer +{ +public: + CRestore( SAVERESTOREDATA *pdata ) : CSaveRestoreBuffer( pdata ), m_global(0), m_precache(TRUE) { } + int ReadEntVars( const char *pname, entvars_t *pev ); // entvars_t + int ReadFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); + int ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount, int startField, int size, char *pName, void *pData ); + int ReadInt( void ); + short ReadShort( void ); + int ReadNamedInt( const char *pName ); + char *ReadNamedString( const char *pName ); + int Empty( void ) { return (m_pdata == NULL) || ((m_pdata->pCurrentData-m_pdata->pBaseData)>=m_pdata->bufferSize); } + inline void SetGlobalMode( int global ) { m_global = global; } + void PrecacheMode( BOOL mode ) { m_precache = mode; } + +private: + char *BufferPointer( void ); + void BufferReadBytes( char *pOutput, int size ); + void BufferSkipBytes( int bytes ); + int BufferSkipZString( void ); + int BufferCheckZString( const char *string ); + + void BufferReadHeader( HEADER *pheader ); + + int m_global; // Restoring a global entity? + BOOL m_precache; +}; + +#define MAX_ENTITYARRAY 64 + +//#define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0])) + +#define IMPLEMENT_SAVERESTORE(derivedClass,baseClass) \ + int derivedClass::Save( CSave &save )\ + {\ + if ( !baseClass::Save(save) )\ + return 0;\ + return save.WriteFields( #derivedClass, this, m_SaveData, ARRAYSIZE(m_SaveData) );\ + }\ + int derivedClass::Restore( CRestore &restore )\ + {\ + if ( !baseClass::Restore(restore) )\ + return 0;\ + return restore.ReadFields( #derivedClass, this, m_SaveData, ARRAYSIZE(m_SaveData) );\ + } + + +typedef enum { GLOBAL_OFF = 0, GLOBAL_ON = 1, GLOBAL_DEAD = 2 } GLOBALESTATE; + +typedef struct globalentity_s globalentity_t; + +struct globalentity_s +{ + char name[64]; + char levelName[32]; + GLOBALESTATE state; + globalentity_t *pNext; +}; + +class CGlobalState +{ +public: + CGlobalState(); + void Reset( void ); + void ClearStates( void ); + void EntityAdd( string_t globalname, string_t mapName, GLOBALESTATE state ); + void EntitySetState( string_t globalname, GLOBALESTATE state ); + void EntityUpdate( string_t globalname, string_t mapname ); + const globalentity_t *EntityFromTable( string_t globalname ); + GLOBALESTATE EntityGetState( string_t globalname ); + int EntityInTable( string_t globalname ) { return (Find( globalname ) != NULL) ? 1 : 0; } + int Save( CSave &save ); + int Restore( CRestore &restore ); + static TYPEDESCRIPTION m_SaveData[]; + +//#ifdef _DEBUG + void DumpGlobals( void ); +//#endif + +private: + globalentity_t *Find( string_t globalname ); + globalentity_t *m_pList; + int m_listCount; + // effc++ rule 11 + void operator=(CGlobalState&); + CGlobalState(const CGlobalState&); +}; + +extern CGlobalState gGlobalState; + +#endif //SAVERESTORE_H diff --git a/sdk/hlsdk/dlls/schedule.h b/sdk/hlsdk/dlls/schedule.h new file mode 100644 index 0000000..52ea044 --- /dev/null +++ b/sdk/hlsdk/dlls/schedule.h @@ -0,0 +1,31 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +//========================================================= +// Scheduling +//========================================================= +#ifndef SCHEDULE_H +#define SCHEDULE_H + +#define bits_COND_SEE_HATE ( 1 << 1 ) // see something that you hate +#define bits_COND_SEE_FEAR ( 1 << 2 ) // see something that you are afraid of +#define bits_COND_SEE_DISLIKE ( 1 << 3 ) // see something that you dislike +#define bits_COND_SEE_ENEMY ( 1 << 4 ) // target entity is in full view. +#define bits_COND_LIGHT_DAMAGE ( 1 << 8 ) // hurt a little +#define bits_COND_HEAVY_DAMAGE ( 1 << 9 ) // hurt a lot +#define bits_COND_SEE_CLIENT ( 1 << 21) // see a client +#define bits_COND_SEE_NEMESIS ( 1 << 22) // see my nemesis + + +#endif // SCHEDULE_H diff --git a/sdk/hlsdk/dlls/scriptevent.h b/sdk/hlsdk/dlls/scriptevent.h new file mode 100644 index 0000000..42377cf --- /dev/null +++ b/sdk/hlsdk/dlls/scriptevent.h @@ -0,0 +1,29 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef SCRIPTEVENT_H +#define SCRIPTEVENT_H + +#define SCRIPT_EVENT_DEAD 1000 // character is now dead +#define SCRIPT_EVENT_NOINTERRUPT 1001 // does not allow interrupt +#define SCRIPT_EVENT_CANINTERRUPT 1002 // will allow interrupt +#define SCRIPT_EVENT_FIREEVENT 1003 // event now fires +#define SCRIPT_EVENT_SOUND 1004 // Play named wave file (on CHAN_BODY) +#define SCRIPT_EVENT_SENTENCE 1005 // Play named sentence +#define SCRIPT_EVENT_INAIR 1006 // Leave the character in air at the end of the sequence (don't find the floor) +#define SCRIPT_EVENT_ENDANIMATION 1007 // Set the animation by name after the sequence completes +#define SCRIPT_EVENT_SOUND_VOICE 1008 // Play named wave file (on CHAN_VOICE) +#define SCRIPT_EVENT_SENTENCE_RND1 1009 // Play sentence group 25% of the time +#define SCRIPT_EVENT_NOT_DEAD 1010 // Bring back to life (for life/death sequences) +#endif //SCRIPTEVENT_H diff --git a/sdk/hlsdk/dlls/skill.h b/sdk/hlsdk/dlls/skill.h new file mode 100644 index 0000000..5ec320c --- /dev/null +++ b/sdk/hlsdk/dlls/skill.h @@ -0,0 +1,147 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +//========================================================= +// skill.h - skill level concerns +//========================================================= + +struct skilldata_t +{ + + int iSkillLevel; // game skill level + +// Monster Health & Damage + float agruntHealth; + float agruntDmgPunch; + + float apacheHealth; + + float barneyHealth; + + float bigmommaHealthFactor; // Multiply each node's health by this + float bigmommaDmgSlash; // melee attack damage + float bigmommaDmgBlast; // mortar attack damage + float bigmommaRadiusBlast; // mortar attack radius + + float bullsquidHealth; + float bullsquidDmgBite; + float bullsquidDmgWhip; + float bullsquidDmgSpit; + + float gargantuaHealth; + float gargantuaDmgSlash; + float gargantuaDmgFire; + float gargantuaDmgStomp; + + float hassassinHealth; + + float headcrabHealth; + float headcrabDmgBite; + + float hgruntHealth; + float hgruntDmgKick; + float hgruntShotgunPellets; + float hgruntGrenadeSpeed; + + float houndeyeHealth; + float houndeyeDmgBlast; + + float slaveHealth; + float slaveDmgClaw; + float slaveDmgClawrake; + float slaveDmgZap; + + float ichthyosaurHealth; + float ichthyosaurDmgShake; + + float leechHealth; + float leechDmgBite; + + float controllerHealth; + float controllerDmgZap; + float controllerSpeedBall; + float controllerDmgBall; + + float nihilanthHealth; + float nihilanthZap; + + float scientistHealth; + + float snarkHealth; + float snarkDmgBite; + float snarkDmgPop; + + float zombieHealth; + float zombieDmgOneSlash; + float zombieDmgBothSlash; + + float turretHealth; + float miniturretHealth; + float sentryHealth; + + +// Player Weapons + float plrDmgCrowbar; + float plrDmg9MM; + float plrDmg357; + float plrDmgMP5; + float plrDmgM203Grenade; + float plrDmgBuckshot; + float plrDmgCrossbowClient; + float plrDmgCrossbowMonster; + float plrDmgRPG; + float plrDmgGauss; + float plrDmgEgonNarrow; + float plrDmgEgonWide; + float plrDmgHornet; + float plrDmgHandGrenade; + float plrDmgSatchel; + float plrDmgTripmine; + +// weapons shared by monsters + float monDmg9MM; + float monDmgMP5; + float monDmg12MM; + float monDmgHornet; + +// health/suit charge + float suitchargerCapacity; + float batteryCapacity; + float healthchargerCapacity; + float healthkitCapacity; + float scientistHeal; + +// monster damage adj + float monHead; + float monChest; + float monStomach; + float monLeg; + float monArm; + +// player damage adj + float plrHead; + float plrChest; + float plrStomach; + float plrLeg; + float plrArm; +}; + +extern DLL_GLOBAL skilldata_t gSkillData; +float GetSkillCvar( char *pName ); + +extern DLL_GLOBAL int g_iSkillLevel; + +#define SKILL_EASY 1 +#define SKILL_MEDIUM 2 +#define SKILL_HARD 3 diff --git a/sdk/hlsdk/dlls/soundent.h b/sdk/hlsdk/dlls/soundent.h new file mode 100644 index 0000000..150daac --- /dev/null +++ b/sdk/hlsdk/dlls/soundent.h @@ -0,0 +1,95 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +//========================================================= +// Soundent.h - the entity that spawns when the world +// spawns, and handles the world's active and free sound +// lists. +//========================================================= + +#define MAX_WORLD_SOUNDS 64 // maximum number of sounds handled by the world at one time. + +#define bits_SOUND_NONE 0 +#define bits_SOUND_COMBAT ( 1 << 0 )// gunshots, explosions +#define bits_SOUND_WORLD ( 1 << 1 )// door opening/closing, glass breaking +#define bits_SOUND_PLAYER ( 1 << 2 )// all noises generated by player. walking, shooting, falling, splashing +#define bits_SOUND_CARCASS ( 1 << 3 )// dead body +#define bits_SOUND_MEAT ( 1 << 4 )// gib or pork chop +#define bits_SOUND_DANGER ( 1 << 5 )// pending danger. Grenade that is about to explode, explosive barrel that is damaged, falling crate +#define bits_SOUND_GARBAGE ( 1 << 6 )// trash cans, banana peels, old fast food bags. + +#define bits_ALL_SOUNDS 0xFFFFFFFF + +#define SOUNDLIST_EMPTY -1 + +#define SOUNDLISTTYPE_FREE 1// identifiers passed to functions that can operate on either list, to indicate which list to operate on. +#define SOUNDLISTTYPE_ACTIVE 2 + +#define SOUND_NEVER_EXPIRE -1 // with this set as a sound's ExpireTime, the sound will never expire. + +//========================================================= +// CSound - an instance of a sound in the world. +//========================================================= +class CSound +{ +public: + + void Clear ( void ); + void Reset ( void ); + + Vector m_vecOrigin; // sound's location in space + int m_iType; // what type of sound this is + int m_iVolume; // how loud the sound is + float m_flExpireTime; // when the sound should be purged from the list + int m_iNext; // index of next sound in this list ( Active or Free ) + int m_iNextAudible; // temporary link that monsters use to build a list of audible sounds + + BOOL FIsSound( void ); + BOOL FIsScent( void ); +}; + +//========================================================= +// CSoundEnt - a single instance of this entity spawns when +// the world spawns. The SoundEnt's job is to update the +// world's Free and Active sound lists. +//========================================================= +class CSoundEnt : public CBaseEntity +{ +public: + + void Precache ( void ); + void Spawn( void ); + void Think( void ); + void Initialize ( void ); + + static void InsertSound ( int iType, const Vector &vecOrigin, int iVolume, float flDuration ); + static void FreeSound ( int iSound, int iPrevious ); + static int ActiveList( void );// return the head of the active list + static int FreeList( void );// return the head of the free list + static CSound* SoundPointerForIndex( int iIndex );// return a pointer for this index in the sound list + static int ClientSoundIndex ( edict_t *pClient ); + + BOOL IsEmpty( void ) { return m_iActiveSound == SOUNDLIST_EMPTY; } + int ISoundsInList ( int iListType ); + int IAllocSound ( void ); + virtual int ObjectCaps( void ) { return FCAP_DONT_SAVE; } + + int m_iFreeSound; // index of the first sound in the free sound list + int m_iActiveSound; // indes of the first sound in the active sound list + int m_cLastActiveSounds; // keeps track of the number of active sounds at the last update. (for diagnostic work) + BOOL m_fShowReport; // if true, dump information about free/active sounds. + +private: + CSound m_SoundPool[ MAX_WORLD_SOUNDS ]; +}; diff --git a/sdk/hlsdk/dlls/spectator.h b/sdk/hlsdk/dlls/spectator.h new file mode 100644 index 0000000..2f755d6 --- /dev/null +++ b/sdk/hlsdk/dlls/spectator.h @@ -0,0 +1,27 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// Spectator.h + +class CBaseSpectator : public CBaseEntity +{ +public: + void Spawn(); + void SpectatorConnect(void); + void SpectatorDisconnect(void); + void SpectatorThink(void); + +private: + void SpectatorImpulseCommand(void); +}; diff --git a/sdk/hlsdk/dlls/talkmonster.h b/sdk/hlsdk/dlls/talkmonster.h new file mode 100644 index 0000000..25c1fc6 --- /dev/null +++ b/sdk/hlsdk/dlls/talkmonster.h @@ -0,0 +1,26 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +#ifndef TALKMONSTER_H +#define TALKMONSTER_H + +class CTalkMonster : public CBaseMonster +{ +public: + static float g_talkWaitTime; + +}; + +#endif //TALKMONSTER_H diff --git a/sdk/hlsdk/dlls/teamplay_gamerules.h b/sdk/hlsdk/dlls/teamplay_gamerules.h new file mode 100644 index 0000000..5d4246b --- /dev/null +++ b/sdk/hlsdk/dlls/teamplay_gamerules.h @@ -0,0 +1,57 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// +// teamplay_gamerules.h +// + +#define MAX_TEAMNAME_LENGTH 16 +#define MAX_TEAMS 32 + +#define TEAMPLAY_TEAMLISTLENGTH MAX_TEAMS*MAX_TEAMNAME_LENGTH + +class CHalfLifeTeamplay : public CHalfLifeMultiplay +{ +public: + CHalfLifeTeamplay(); + + virtual BOOL ClientCommand( CBasePlayer *pPlayer, const char *pcmd ); + virtual void ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ); + virtual BOOL IsTeamplay( void ); + virtual BOOL FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ); + virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ); + virtual const char *GetTeamID( CBaseEntity *pEntity ); + virtual BOOL ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target ); + virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ); + virtual void InitHUD( CBasePlayer *pl ); + virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor ); + virtual const char *GetGameDescription( void ) { return "HL Teamplay"; } // this is the game name that gets seen in the server browser + virtual void UpdateGameMode( CBasePlayer *pPlayer ); // the client needs to be informed of the current game mode + virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); + virtual void Think ( void ); + virtual int GetTeamIndex( const char *pTeamName ); + virtual const char *GetIndexedTeamName( int teamIndex ); + virtual BOOL IsValidTeam( const char *pTeamName ); + const char *SetDefaultPlayerTeam( CBasePlayer *pPlayer ); + virtual void ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib ); + +private: + void RecountTeams( bool bResendInfo = FALSE ); + const char *TeamWithFewestPlayers( void ); + + BOOL m_DisableDeathMessages; + BOOL m_DisableDeathPenalty; + BOOL m_teamLimit; // This means the server set only some teams as valid + char m_szTeamList[TEAMPLAY_TEAMLISTLENGTH]; +}; diff --git a/sdk/hlsdk/dlls/trains.h b/sdk/hlsdk/dlls/trains.h new file mode 100644 index 0000000..87aec76 --- /dev/null +++ b/sdk/hlsdk/dlls/trains.h @@ -0,0 +1,127 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef TRAINS_H +#define TRAINS_H + +// Tracktrain spawn flags +#define SF_TRACKTRAIN_NOPITCH 0x0001 +#define SF_TRACKTRAIN_NOCONTROL 0x0002 +#define SF_TRACKTRAIN_FORWARDONLY 0x0004 +#define SF_TRACKTRAIN_PASSABLE 0x0008 + +// Spawnflag for CPathTrack +#define SF_PATH_DISABLED 0x00000001 +#define SF_PATH_FIREONCE 0x00000002 +#define SF_PATH_ALTREVERSE 0x00000004 +#define SF_PATH_DISABLE_TRAIN 0x00000008 +#define SF_PATH_ALTERNATE 0x00008000 + +// Spawnflags of CPathCorner +#define SF_CORNER_WAITFORTRIG 0x001 +#define SF_CORNER_TELEPORT 0x002 +#define SF_CORNER_FIREONCE 0x004 + +//#define PATH_SPARKLE_DEBUG 1 // This makes a particle effect around path_track entities for debugging +class CPathTrack : public CPointEntity +{ +public: + void Spawn( void ); + void Activate( void ); + void KeyValue( KeyValueData* pkvd); + + void SetPrevious( CPathTrack *pprevious ); + void Link( void ); + void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + + CPathTrack *ValidPath( CPathTrack *ppath, int testFlag ); // Returns ppath if enabled, NULL otherwise + void Project( CPathTrack *pstart, CPathTrack *pend, Vector *origin, float dist ); + + static CPathTrack *Instance( edict_t *pent ); + + CPathTrack *LookAhead( Vector *origin, float dist, int move ); + CPathTrack *Nearest( Vector origin ); + + CPathTrack *GetNext( void ); + CPathTrack *GetPrevious( void ); + + virtual int Save( CSave &save ); + virtual int Restore( CRestore &restore ); + + static TYPEDESCRIPTION m_SaveData[]; +#if PATH_SPARKLE_DEBUG + void EXPORT Sparkle(void); +#endif + + float m_length; + string_t m_altName; + CPathTrack *m_pnext; + CPathTrack *m_pprevious; + CPathTrack *m_paltpath; +}; + + +class CFuncTrackTrain : public CBaseEntity +{ +public: + void Spawn( void ); + void Precache( void ); + + void Blocked( CBaseEntity *pOther ); + void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + void KeyValue( KeyValueData* pkvd ); + + void EXPORT Next( void ); + void EXPORT Find( void ); + void EXPORT NearestPath( void ); + void EXPORT DeadEnd( void ); + + void NextThink( float thinkTime, BOOL alwaysThink ); + + void SetTrack( CPathTrack *track ) { m_ppath = track->Nearest(pev->origin); } + void SetControls( entvars_t *pevControls ); + BOOL OnControls( entvars_t *pev ); + + void StopSound ( void ); + void UpdateSound ( void ); + + static CFuncTrackTrain *Instance( edict_t *pent ); + + virtual int Save( CSave &save ); + virtual int Restore( CRestore &restore ); + + static TYPEDESCRIPTION m_SaveData[]; + virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DIRECTIONAL_USE; } + + virtual void OverrideReset( void ); + + CPathTrack *m_ppath; + float m_length; + float m_height; + float m_speed; + float m_dir; + float m_startSpeed; + Vector m_controlMins; + Vector m_controlMaxs; + int m_soundPlaying; + int m_sounds; + float m_flVolume; + float m_flBank; + float m_oldSpeed; + +private: + unsigned short m_usAdjustPitch; +}; + +#endif diff --git a/sdk/hlsdk/dlls/util.h b/sdk/hlsdk/dlls/util.h new file mode 100644 index 0000000..ddda087 --- /dev/null +++ b/sdk/hlsdk/dlls/util.h @@ -0,0 +1,541 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// +// Misc utility code +// +#include +#ifndef ACTIVITY_H +#include "activity.h" +#endif + +#ifndef ENGINECALLBACK_H +#include "enginecallback.h" +#endif +inline void MESSAGE_BEGIN( int msg_dest, int msg_type, const float *pOrigin, entvars_t *ent ); // implementation later in this file + +extern globalvars_t *gpGlobals; + +// Use this instead of ALLOC_STRING on constant strings +#define STRING(offset) (const char *)(gpGlobals->pStringBase + (int)offset) +#define MAKE_STRING(str) ((int)str - (int)STRING(0)) + +inline edict_t *FIND_ENTITY_BY_CLASSNAME(edict_t *entStart, const char *pszName) +{ + return FIND_ENTITY_BY_STRING(entStart, "classname", pszName); +} + +inline edict_t *FIND_ENTITY_BY_TARGETNAME(edict_t *entStart, const char *pszName) +{ + return FIND_ENTITY_BY_STRING(entStart, "targetname", pszName); +} + +// for doing a reverse lookup. Say you have a door, and want to find its button. +inline edict_t *FIND_ENTITY_BY_TARGET(edict_t *entStart, const char *pszName) +{ + return FIND_ENTITY_BY_STRING(entStart, "target", pszName); +} + +// Keeps clutter down a bit, when writing key-value pairs +#define WRITEKEY_INT(pf, szKeyName, iKeyValue) ENGINE_FPRINTF(pf, "\"%s\" \"%d\"\n", szKeyName, iKeyValue) +#define WRITEKEY_FLOAT(pf, szKeyName, flKeyValue) \ + ENGINE_FPRINTF(pf, "\"%s\" \"%f\"\n", szKeyName, flKeyValue) +#define WRITEKEY_STRING(pf, szKeyName, szKeyValue) \ + ENGINE_FPRINTF(pf, "\"%s\" \"%s\"\n", szKeyName, szKeyValue) +#define WRITEKEY_VECTOR(pf, szKeyName, flX, flY, flZ) \ + ENGINE_FPRINTF(pf, "\"%s\" \"%f %f %f\"\n", szKeyName, flX, flY, flZ) + +// Keeps clutter down a bit, when using a float as a bit-vector +#define SetBits(flBitVector, bits) ((flBitVector) = (int)(flBitVector) | (bits)) +#define ClearBits(flBitVector, bits) ((flBitVector) = (int)(flBitVector) & ~(bits)) +#define FBitSet(flBitVector, bit) ((int)(flBitVector) & (bit)) + +// Makes these more explicit, and easier to find +#define FILE_GLOBAL static +#define DLL_GLOBAL + +// Until we figure out why "const" gives the compiler problems, we'll just have to use +// this bogus "empty" define to mark things as constant. +#define CONSTANT + +// More explicit than "int" +typedef int EOFFSET; + +// In case it's not alread defined +typedef int BOOL; + +// In case this ever changes +#define M_PI 3.14159265358979323846 + +// Keeps clutter down a bit, when declaring external entity/global method prototypes +#define DECLARE_GLOBAL_METHOD(MethodName) extern void DLLEXPORT MethodName( void ) +#define GLOBAL_METHOD(funcname) void DLLEXPORT funcname(void) + +// This is the glue that hooks .MAP entity class names to our CPP classes +// The _declspec forces them to be exported by name so we can do a lookup with GetProcAddress() +// The function is used to intialize / allocate the object for the entity +#ifdef _WIN32 +#define LINK_ENTITY_TO_CLASS(mapClassName,DLLClassName) \ + extern "C" _declspec( dllexport ) void mapClassName( entvars_t *pev ); \ + void mapClassName( entvars_t *pev ) { GetClassPtr( (DLLClassName *)pev ); } +#else +#define LINK_ENTITY_TO_CLASS(mapClassName,DLLClassName) extern "C" void mapClassName( entvars_t *pev ); void mapClassName( entvars_t *pev ) { GetClassPtr( (DLLClassName *)pev ); } +#endif + + +// +// Conversion among the three types of "entity", including identity-conversions. +// +#ifdef DEBUG + extern edict_t *DBG_EntOfVars(const entvars_t *pev); + inline edict_t *ENT(const entvars_t *pev) { return DBG_EntOfVars(pev); } +#else + inline edict_t *ENT(const entvars_t *pev) { return pev->pContainingEntity; } +#endif +inline edict_t *ENT(edict_t *pent) { return pent; } +inline edict_t *ENT(EOFFSET eoffset) { return (*g_engfuncs.pfnPEntityOfEntOffset)(eoffset); } +inline EOFFSET OFFSET(EOFFSET eoffset) { return eoffset; } +inline EOFFSET OFFSET(const edict_t *pent) +{ +#ifdef _DEBUG + if ( !pent ) + ALERT( at_error, "Bad ent in OFFSET()\n" ); +#endif + return (*g_engfuncs.pfnEntOffsetOfPEntity)(pent); +} +inline EOFFSET OFFSET(entvars_t *pev) +{ +#ifdef _DEBUG + if ( !pev ) + ALERT( at_error, "Bad pev in OFFSET()\n" ); +#endif + return OFFSET(ENT(pev)); +} +inline entvars_t *VARS(entvars_t *pev) { return pev; } + +inline entvars_t *VARS(edict_t *pent) +{ + if ( !pent ) + return NULL; + + return &pent->v; +} + +inline entvars_t* VARS(EOFFSET eoffset) { return VARS(ENT(eoffset)); } +inline int ENTINDEX(edict_t *pEdict) { return (*g_engfuncs.pfnIndexOfEdict)(pEdict); } +inline edict_t* INDEXENT( int iEdictNum ) { return (*g_engfuncs.pfnPEntityOfEntIndex)(iEdictNum); } +inline void MESSAGE_BEGIN( int msg_dest, int msg_type, const float *pOrigin, entvars_t *ent ) { + (*g_engfuncs.pfnMessageBegin)(msg_dest, msg_type, pOrigin, ENT(ent)); +} + +// Testing the three types of "entity" for nullity +#define eoNullEntity 0 +inline BOOL FNullEnt(EOFFSET eoffset) { return eoffset == 0; } +inline BOOL FNullEnt(const edict_t* pent) { return pent == NULL || FNullEnt(OFFSET(pent)); } +inline BOOL FNullEnt(entvars_t* pev) { return pev == NULL || FNullEnt(OFFSET(pev)); } + +// Testing strings for nullity +#define iStringNull 0 +inline BOOL FStringNull(int iString) { return iString == iStringNull; } + +#define cchMapNameMost 32 + +// Dot products for view cone checking +#define VIEW_FIELD_FULL (float)-1.0 // +-180 degrees +#define VIEW_FIELD_WIDE (float)-0.7 // +-135 degrees 0.1 // +-85 degrees, used for full FOV checks +#define VIEW_FIELD_NARROW (float)0.7 // +-45 degrees, more narrow check used to set up ranged attacks +#define VIEW_FIELD_ULTRA_NARROW (float)0.9 // +-25 degrees, more narrow check used to set up ranged attacks + +// All monsters need this data +#define DONT_BLEED -1 +#define BLOOD_COLOR_RED (BYTE)247 +#define BLOOD_COLOR_YELLOW (BYTE)195 +#define BLOOD_COLOR_GREEN BLOOD_COLOR_YELLOW + +typedef enum +{ + + MONSTERSTATE_NONE = 0, + MONSTERSTATE_IDLE, + MONSTERSTATE_COMBAT, + MONSTERSTATE_ALERT, + MONSTERSTATE_HUNT, + MONSTERSTATE_PRONE, + MONSTERSTATE_SCRIPT, + MONSTERSTATE_PLAYDEAD, + MONSTERSTATE_DEAD + +} MONSTERSTATE; + + + +// Things that toggle (buttons/triggers/doors) need this +typedef enum + { + TS_AT_TOP, + TS_AT_BOTTOM, + TS_GOING_UP, + TS_GOING_DOWN + } TOGGLE_STATE; + +// Misc useful +inline BOOL FStrEq(const char*sz1, const char*sz2) + { return (strcmp(sz1, sz2) == 0); } +inline BOOL FClassnameIs(edict_t* pent, const char* szClassname) + { return FStrEq(STRING(VARS(pent)->classname), szClassname); } +inline BOOL FClassnameIs(entvars_t* pev, const char* szClassname) + { return FStrEq(STRING(pev->classname), szClassname); } + +class CBaseEntity; + +// Misc. Prototypes +extern void UTIL_SetSize (entvars_t* pev, const Vector &vecMin, const Vector &vecMax); +extern float UTIL_VecToYaw (const Vector &vec); +extern Vector UTIL_VecToAngles (const Vector &vec); +extern float UTIL_AngleMod (float a); +extern float UTIL_AngleDiff ( float destAngle, float srcAngle ); + +extern CBaseEntity *UTIL_FindEntityInSphere(CBaseEntity *pStartEntity, const Vector &vecCenter, float flRadius); +extern CBaseEntity *UTIL_FindEntityByString(CBaseEntity *pStartEntity, const char *szKeyword, const char *szValue ); +extern CBaseEntity *UTIL_FindEntityByClassname(CBaseEntity *pStartEntity, const char *szName ); +extern CBaseEntity *UTIL_FindEntityByTargetname(CBaseEntity *pStartEntity, const char *szName ); +extern CBaseEntity *UTIL_FindEntityGeneric(const char *szName, Vector &vecSrc, float flRadius ); + +// returns a CBaseEntity pointer to a player by index. Only returns if the player is spawned and connected +// otherwise returns NULL +// Index is 1 based +extern CBaseEntity *UTIL_PlayerByIndex( int playerIndex ); + +#define UTIL_EntitiesInPVS(pent) (*g_engfuncs.pfnEntitiesInPVS)(pent) +extern void UTIL_MakeVectors (const Vector &vecAngles); + +// Pass in an array of pointers and an array size, it fills the array and returns the number inserted +extern int UTIL_MonstersInSphere( CBaseEntity **pList, int listMax, const Vector ¢er, float radius ); +extern int UTIL_EntitiesInBox( CBaseEntity **pList, int listMax, const Vector &mins, const Vector &maxs, int flagMask ); + +inline void UTIL_MakeVectorsPrivate( const Vector &vecAngles, float *p_vForward, float *p_vRight, float *p_vUp ) +{ + g_engfuncs.pfnAngleVectors( vecAngles, p_vForward, p_vRight, p_vUp ); +} + +extern void UTIL_MakeAimVectors ( const Vector &vecAngles ); // like MakeVectors, but assumes pitch isn't inverted +extern void UTIL_MakeInvVectors ( const Vector &vec, globalvars_t *pgv ); + +extern void UTIL_SetOrigin ( entvars_t* pev, const Vector &vecOrigin ); +extern void UTIL_EmitAmbientSound ( edict_t *entity, const Vector &vecOrigin, const char *samp, float vol, float attenuation, int fFlags, int pitch ); +extern void UTIL_ParticleEffect ( const Vector &vecOrigin, const Vector &vecDirection, ULONG ulColor, ULONG ulCount ); +extern void UTIL_ScreenShake ( const Vector ¢er, float amplitude, float frequency, float duration, float radius ); +extern void UTIL_ScreenShakeAll ( const Vector ¢er, float amplitude, float frequency, float duration ); +extern void UTIL_ShowMessage ( const char *pString, CBaseEntity *pPlayer ); +extern void UTIL_ShowMessageAll ( const char *pString ); +extern void UTIL_ScreenFadeAll ( const Vector &color, float fadeTime, float holdTime, int alpha, int flags ); +extern void UTIL_ScreenFade ( CBaseEntity *pEntity, const Vector &color, float fadeTime, float fadeHold, int alpha, int flags ); + +typedef enum { ignore_monsters=1, dont_ignore_monsters=0, missile=2 } IGNORE_MONSTERS; +typedef enum { ignore_glass=1, dont_ignore_glass=0 } IGNORE_GLASS; +extern void UTIL_TraceLine (const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, edict_t *pentIgnore, TraceResult *ptr); +extern void UTIL_TraceLine (const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, IGNORE_GLASS ignoreGlass, edict_t *pentIgnore, TraceResult *ptr); +typedef enum { point_hull=0, human_hull=1, large_hull=2, head_hull=3 } __HLSDK_HULL_TYPE; +extern void UTIL_TraceHull (const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, int hullNumber, edict_t *pentIgnore, TraceResult *ptr); +extern TraceResult UTIL_GetGlobalTrace (void); +extern void UTIL_TraceModel (const Vector &vecStart, const Vector &vecEnd, int hullNumber, edict_t *pentModel, TraceResult *ptr); +extern Vector UTIL_GetAimVector (edict_t* pent, float flSpeed); +extern int UTIL_PointContents (const Vector &vec); + +extern int UTIL_IsMasterTriggered (string_t sMaster, CBaseEntity *pActivator); +extern void UTIL_BloodStream( const Vector &origin, const Vector &direction, int color, int amount ); +extern void UTIL_BloodDrips( const Vector &origin, const Vector &direction, int color, int amount ); +extern Vector UTIL_RandomBloodVector( void ); +extern BOOL UTIL_ShouldShowBlood( int bloodColor ); +extern void UTIL_BloodDecalTrace( TraceResult *pTrace, int bloodColor ); +extern void UTIL_DecalTrace( TraceResult *pTrace, int decalNumber ); +extern void UTIL_PlayerDecalTrace( TraceResult *pTrace, int playernum, int decalNumber, BOOL bIsCustom ); +extern void UTIL_GunshotDecalTrace( TraceResult *pTrace, int decalNumber ); +extern void UTIL_Sparks( const Vector &position ); +extern void UTIL_Ricochet( const Vector &position, float scale ); +extern void UTIL_StringToVector( float *pVector, const char *pString ); +extern void UTIL_StringToIntArray( int *pVector, int count, const char *pString ); +extern Vector UTIL_ClampVectorToBox( const Vector &input, const Vector &clampSize ); +extern float UTIL_Approach( float target, float value, float speed ); +extern float UTIL_ApproachAngle( float target, float value, float speed ); +extern float UTIL_AngleDistance( float next, float cur ); + +extern char *UTIL_VarArgs( char *format, ... ); +extern void UTIL_Remove( CBaseEntity *pEntity ); +extern BOOL UTIL_IsValidEntity( edict_t *pent ); +extern BOOL UTIL_TeamsMatch( const char *pTeamName1, const char *pTeamName2 ); + +// Use for ease-in, ease-out style interpolation (accel/decel) +extern float UTIL_SplineFraction( float value, float scale ); + +// Search for water transition along a vertical line +extern float UTIL_WaterLevel( const Vector &position, float minz, float maxz ); +extern void UTIL_Bubbles( Vector mins, Vector maxs, int count ); +extern void UTIL_BubbleTrail( Vector from, Vector to, int count ); + +// allows precacheing of other entities +extern void UTIL_PrecacheOther( const char *szClassname ); + +// prints a message to each client +extern void UTIL_ClientPrintAll( int msg_dest, const char *msg_name, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL ); +inline void UTIL_CenterPrintAll( const char *msg_name, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL ) +{ + UTIL_ClientPrintAll( HUD_PRINTCENTER, msg_name, param1, param2, param3, param4 ); +} + +class CBasePlayerItem; +class CBasePlayer; +extern BOOL UTIL_GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ); + +// prints messages through the HUD +extern void ClientPrint( entvars_t *client, int msg_dest, const char *msg_name, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL ); + +// prints a message to the HUD say (chat) +extern void UTIL_SayText( const char *pText, CBaseEntity *pEntity ); +extern void UTIL_SayTextAll( const char *pText, CBaseEntity *pEntity ); + + +typedef struct hudtextparms_s +{ + float x; + float y; + int effect; + byte r1, g1, b1, a1; + byte r2, g2, b2, a2; + float fadeinTime; + float fadeoutTime; + float holdTime; + float fxTime; + int channel; +} hudtextparms_t; + +// prints as transparent 'title' to the HUD +extern void UTIL_HudMessageAll( const hudtextparms_t &textparms, const char *pMessage ); +extern void UTIL_HudMessage( CBaseEntity *pEntity, const hudtextparms_t &textparms, const char *pMessage ); + +// for handy use with ClientPrint params +extern char *UTIL_dtos1( int d ); +extern char *UTIL_dtos2( int d ); +extern char *UTIL_dtos3( int d ); +extern char *UTIL_dtos4( int d ); + +// Writes message to console with timestamp and FragLog header. +extern void UTIL_LogPrintf( char *fmt, ... ); + +// Sorta like FInViewCone, but for nonmonsters. +extern float UTIL_DotPoints ( const Vector &vecSrc, const Vector &vecCheck, const Vector &vecDir ); + +extern void UTIL_StripToken( const char *pKey, char *pDest );// for redundant keynames + +// Misc functions +extern void SetMovedir(entvars_t* pev); +extern Vector VecBModelOrigin( entvars_t* pevBModel ); +extern int BuildChangeList( LEVELLIST *pLevelList, int maxList ); + +// +// How did I ever live without ASSERT? +// +#ifdef DEBUG +void DBG_AssertFunction(BOOL fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage); +#define ASSERT(f) DBG_AssertFunction(f, #f, __FILE__, __LINE__, NULL) +#define ASSERTSZ(f, sz) DBG_AssertFunction(f, #f, __FILE__, __LINE__, sz) +#else // !DEBUG +#define ASSERT(f) +#define ASSERTSZ(f, sz) +#endif // !DEBUG + + +extern DLL_GLOBAL const Vector g_vecZero; + +// +// Constants that were used only by QC (maybe not used at all now) +// +// Un-comment only as needed +// +#define LANGUAGE_ENGLISH 0 +#define LANGUAGE_GERMAN 1 +#define LANGUAGE_FRENCH 2 +#define LANGUAGE_BRITISH 3 + +extern DLL_GLOBAL int g_Language; + +#define AMBIENT_SOUND_STATIC 0 // medium radius attenuation +#define AMBIENT_SOUND_EVERYWHERE 1 +#define AMBIENT_SOUND_SMALLRADIUS 2 +#define AMBIENT_SOUND_MEDIUMRADIUS 4 +#define AMBIENT_SOUND_LARGERADIUS 8 +#define AMBIENT_SOUND_START_SILENT 16 +#define AMBIENT_SOUND_NOT_LOOPING 32 + +#define SPEAKER_START_SILENT 1 // wait for trigger 'on' to start announcements + +#define SND_SPAWNING (1<<8) // duplicated in protocol.h we're spawing, used in some cases for ambients +#define SND_STOP (1<<5) // duplicated in protocol.h stop sound +#define SND_CHANGE_VOL (1<<6) // duplicated in protocol.h change sound vol +#define SND_CHANGE_PITCH (1<<7) // duplicated in protocol.h change sound pitch + +#define LFO_SQUARE 1 +#define LFO_TRIANGLE 2 +#define LFO_RANDOM 3 + +// func_rotating +#define SF_BRUSH_ROTATE_Y_AXIS 0 +#define SF_BRUSH_ROTATE_INSTANT 1 +#define SF_BRUSH_ROTATE_BACKWARDS 2 +#define SF_BRUSH_ROTATE_Z_AXIS 4 +#define SF_BRUSH_ROTATE_X_AXIS 8 +#define SF_PENDULUM_AUTO_RETURN 16 +#define SF_PENDULUM_PASSABLE 32 + + +#define SF_BRUSH_ROTATE_SMALLRADIUS 128 +#define SF_BRUSH_ROTATE_MEDIUMRADIUS 256 +#define SF_BRUSH_ROTATE_LARGERADIUS 512 + +#define PUSH_BLOCK_ONLY_X 1 +#define PUSH_BLOCK_ONLY_Y 2 + +#define VEC_HULL_MIN Vector(-16, -16, -36) +#define VEC_HULL_MAX Vector( 16, 16, 36) +#define VEC_HUMAN_HULL_MIN Vector( -16, -16, 0 ) +#define VEC_HUMAN_HULL_MAX Vector( 16, 16, 72 ) +#define VEC_HUMAN_HULL_DUCK Vector( 16, 16, 36 ) + +#define VEC_VIEW Vector( 0, 0, 28 ) + +#define VEC_DUCK_HULL_MIN Vector(-16, -16, -18 ) +#define VEC_DUCK_HULL_MAX Vector( 16, 16, 18) +#define VEC_DUCK_VIEW Vector( 0, 0, 12 ) + +#define SVC_TEMPENTITY 23 +#define SVC_INTERMISSION 30 +#define SVC_CDTRACK 32 +#define SVC_WEAPONANIM 35 +#define SVC_ROOMTYPE 37 +#define SVC_DIRECTOR 51 + + + +// triggers +#define SF_TRIGGER_ALLOWMONSTERS 1// monsters allowed to fire this trigger +#define SF_TRIGGER_NOCLIENTS 2// players not allowed to fire this trigger +#define SF_TRIGGER_PUSHABLES 4// only pushables can fire this trigger + +// func breakable +#define SF_BREAK_TRIGGER_ONLY 1// may only be broken by trigger +#define SF_BREAK_TOUCH 2// can be 'crashed through' by running player (plate glass) +#define SF_BREAK_PRESSURE 4// can be broken by a player standing on it +#define SF_BREAK_CROWBAR 256// instant break if hit with crowbar + +// func_pushable (it's also func_breakable, so don't collide with those flags) +#define SF_PUSH_BREAKABLE 128 + +#define SF_LIGHT_START_OFF 1 + +#define SPAWNFLAG_NOMESSAGE 1 +#define SPAWNFLAG_NOTOUCH 1 +#define SPAWNFLAG_DROIDONLY 4 + +#define SPAWNFLAG_USEONLY 1 // can't be touched, must be used (buttons) + +#define TELE_PLAYER_ONLY 1 +#define TELE_SILENT 2 + +#define SF_TRIG_PUSH_ONCE 1 + + +// Sound Utilities + +// sentence groups +#define CBSENTENCENAME_MAX 16 +#define CVOXFILESENTENCEMAX 1536 // max number of sentences in game. NOTE: this must match + // CVOXFILESENTENCEMAX in engine\sound.h!!! + +extern char gszallsentencenames[CVOXFILESENTENCEMAX][CBSENTENCENAME_MAX]; +extern int gcallsentences; + +int USENTENCEG_Pick(int isentenceg, char *szfound); +int USENTENCEG_PickSequential(int isentenceg, char *szfound, int ipick, int freset); +void USENTENCEG_InitLRU(unsigned char *plru, int count); + +void SENTENCEG_Init(); +void SENTENCEG_Stop(edict_t *entity, int isentenceg, int ipick); +int SENTENCEG_PlayRndI(edict_t *entity, int isentenceg, float volume, float attenuation, int flags, int pitch); +int SENTENCEG_PlayRndSz(edict_t *entity, const char *szrootname, float volume, float attenuation, int flags, int pitch); +int SENTENCEG_PlaySequentialSz(edict_t *entity, const char *szrootname, float volume, float attenuation, int flags, int pitch, int ipick, int freset); +int SENTENCEG_GetIndex(const char *szrootname); +int SENTENCEG_Lookup(const char *sample, char *sentencenum); + +void TEXTURETYPE_Init(); +char TEXTURETYPE_Find(char *name); +float TEXTURETYPE_PlaySound(TraceResult *ptr, Vector vecSrc, Vector vecEnd, int iBulletType); + +// NOTE: use EMIT_SOUND_DYN to set the pitch of a sound. Pitch of 100 +// is no pitch shift. Pitch > 100 up to 255 is a higher pitch, pitch < 100 +// down to 1 is a lower pitch. 150 to 70 is the realistic range. +// EMIT_SOUND_DYN with pitch != 100 should be used sparingly, as it's not quite as +// fast as EMIT_SOUND (the pitchshift mixer is not native coded). + +void EMIT_SOUND_DYN(edict_t *entity, int channel, const char *sample, float volume, float attenuation, + int flags, int pitch); + + +inline void EMIT_SOUND(edict_t *entity, int channel, const char *sample, float volume, float attenuation) +{ + EMIT_SOUND_DYN(entity, channel, sample, volume, attenuation, 0, PITCH_NORM); +} + +inline void STOP_SOUND(edict_t *entity, int channel, const char *sample) +{ + EMIT_SOUND_DYN(entity, channel, sample, 0, 0, SND_STOP, PITCH_NORM); +} + +void EMIT_SOUND_SUIT(edict_t *entity, const char *sample); +void EMIT_GROUPID_SUIT(edict_t *entity, int isentenceg); +void EMIT_GROUPNAME_SUIT(edict_t *entity, const char *groupname); + +#define PRECACHE_SOUND_ARRAY( a ) \ + { for (int i = 0; i < ARRAYSIZE( a ); i++ ) PRECACHE_SOUND((char *) a [i]); } + +#define EMIT_SOUND_ARRAY_DYN( chan, array ) \ + EMIT_SOUND_DYN ( ENT(pev), chan , array [ RANDOM_LONG(0,ARRAYSIZE( array )-1) ], 1.0, ATTN_NORM, 0, RANDOM_LONG(95,105) ); + +#define RANDOM_SOUND_ARRAY( array ) (array) [ RANDOM_LONG(0,ARRAYSIZE( (array) )-1) ] + +#define PLAYBACK_EVENT( flags, who, index ) PLAYBACK_EVENT_FULL( flags, who, index, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); +#define PLAYBACK_EVENT_DELAY( flags, who, index, delay ) PLAYBACK_EVENT_FULL( flags, who, index, delay, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); + +#define GROUP_OP_AND 0 +#define GROUP_OP_NAND 1 + +extern int g_groupmask; +extern int g_groupop; + +class UTIL_GroupTrace +{ +public: + UTIL_GroupTrace( int groupmask, int op ); + ~UTIL_GroupTrace( void ); + +private: + int m_oldgroupmask, m_oldgroupop; +}; + +void UTIL_SetGroupTrace( int groupmask, int op ); +void UTIL_UnsetGroupTrace( void ); + +int UTIL_SharedRandomLong( unsigned int seed, int low, int high ); +float UTIL_SharedRandomFloat( unsigned int seed, float low, float high ); + +float UTIL_WeaponTimeBase( void ); diff --git a/sdk/hlsdk/dlls/vector.h b/sdk/hlsdk/dlls/vector.h new file mode 100644 index 0000000..e51c859 --- /dev/null +++ b/sdk/hlsdk/dlls/vector.h @@ -0,0 +1,112 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef VECTOR_H +#define VECTOR_H + +//========================================================= +// 2DVector - used for many pathfinding and many other +// operations that are treated as planar rather than 3d. +//========================================================= +class Vector2D +{ +public: + inline Vector2D(void): x(0.0), y(0.0) { } + inline Vector2D(float X, float Y): x(0.0), y(0.0) { x = X; y = Y; } + inline Vector2D operator+(const Vector2D& v) const { return Vector2D(x+v.x, y+v.y); } + inline Vector2D operator-(const Vector2D& v) const { return Vector2D(x-v.x, y-v.y); } + inline Vector2D operator*(float fl) const { return Vector2D(x*fl, y*fl); } + inline Vector2D operator/(float fl) const { return Vector2D(x/fl, y/fl); } + + inline float Length(void) const { return sqrt(x*x + y*y ); } + + inline Vector2D Normalize ( void ) const + { + // Vector2D vec2; + + float flLen = Length(); + if ( flLen == 0 ) + { + return Vector2D( 0, 0 ); + } + else + { + flLen = 1 / flLen; + return Vector2D( x * flLen, y * flLen ); + } + } + + vec_t x, y; +}; + +inline float DotProduct(const Vector2D& a, const Vector2D& b) { return( a.x*b.x + a.y*b.y ); } +inline Vector2D operator*(float fl, const Vector2D& v) { return v * fl; } + +//========================================================= +// 3D Vector +//========================================================= +class Vector // same data-layout as engine's vec3_t, +{ // which is a vec_t[3] +public: + // Construction/destruction + inline Vector(void): x(0.0), y(0.0), z(0.0) { } + inline Vector(float X, float Y, float Z): x(0.0), y(0.0), z(0.0) { x = X; y = Y; z = Z; } + //inline Vector(double X, double Y, double Z) { x = (float)X; y = (float)Y; z = (float)Z; } + //inline Vector(int X, int Y, int Z) { x = (float)X; y = (float)Y; z = (float)Z; } + inline Vector(const Vector& v): x(0.0), y(0.0), z(0.0) { x = v.x; y = v.y; z = v.z; } + inline Vector(float rgfl[3]): x(0.0), y(0.0), z(0.0) { x = rgfl[0]; y = rgfl[1]; z = rgfl[2]; } + + // Operators + inline Vector operator-(void) const { return Vector(-x,-y,-z); } + inline int operator==(const Vector& v) const { return x==v.x && y==v.y && z==v.z; } + inline int operator!=(const Vector& v) const { return !(*this==v); } + inline Vector operator+(const Vector& v) const { return Vector(x+v.x, y+v.y, z+v.z); } + inline Vector operator-(const Vector& v) const { return Vector(x-v.x, y-v.y, z-v.z); } + inline Vector operator*(float fl) const { return Vector(x*fl, y*fl, z*fl); } + inline Vector operator/(float fl) const { return Vector(x/fl, y/fl, z/fl); } + + // Methods + inline void CopyToArray(float* rgfl) const { rgfl[0] = x, rgfl[1] = y, rgfl[2] = z; } + inline float Length(void) const { return sqrt(x*x + y*y + z*z); } + operator float *() { return &x; } // Vectors will now automatically convert to float * when needed + operator const float *() const { return &x; } // Vectors will now automatically convert to float * when needed + inline Vector Normalize(void) const + { + float flLen = Length(); + if (flLen == 0) return Vector(0,0,1); // ???? + flLen = 1 / flLen; + return Vector(x * flLen, y * flLen, z * flLen); + } + + inline Vector2D Make2D ( void ) const + { + Vector2D Vec2; + + Vec2.x = x; + Vec2.y = y; + + return Vec2; + } + inline float Length2D(void) const { return sqrt(x*x + y*y); } + + // Members + vec_t x, y, z; +}; +inline Vector operator*(float fl, const Vector& v) { return v * fl; } +inline float DotProduct(const Vector& a, const Vector& b) { return(a.x*b.x+a.y*b.y+a.z*b.z); } +inline Vector CrossProduct(const Vector& a, const Vector& b) { return Vector( a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x ); } + + + +#endif diff --git a/sdk/hlsdk/dlls/weapons.h b/sdk/hlsdk/dlls/weapons.h new file mode 100644 index 0000000..8194a4d --- /dev/null +++ b/sdk/hlsdk/dlls/weapons.h @@ -0,0 +1,1015 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef WEAPONS_H +#define WEAPONS_H + +#include "effects.h" + +class CBasePlayer; +extern int gmsgWeapPickup; + +void DeactivateSatchels( CBasePlayer *pOwner ); + +// Contact Grenade / Timed grenade / Satchel Charge +class CGrenade : public CBaseMonster +{ +public: + void Spawn( void ); + + typedef enum { SATCHEL_DETONATE = 0, SATCHEL_RELEASE } SATCHELCODE; + + static CGrenade *ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time ); + static CGrenade *ShootContact( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity ); + static CGrenade *ShootSatchelCharge( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity ); + static void UseSatchelCharges( entvars_t *pevOwner, SATCHELCODE code ); + + void Explode( Vector vecSrc, Vector vecAim ); + void Explode( TraceResult *pTrace, int bitsDamageType ); + void EXPORT Smoke( void ); + + void EXPORT BounceTouch( CBaseEntity *pOther ); + void EXPORT SlideTouch( CBaseEntity *pOther ); + void EXPORT ExplodeTouch( CBaseEntity *pOther ); + void EXPORT DangerSoundThink( void ); + void EXPORT PreDetonate( void ); + void EXPORT Detonate( void ); + void EXPORT DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + void EXPORT TumbleThink( void ); + + virtual void BounceSound( void ); + virtual int BloodColor( void ) { return DONT_BLEED; } + virtual void Killed( entvars_t *pevAttacker, int iGib ); + + BOOL m_fRegisteredSound;// whether or not this grenade has issued its DANGER sound to the world sound list yet. +}; + + +// constant items +#define ITEM_HEALTHKIT 1 +#define ITEM_ANTIDOTE 2 +#define ITEM_SECURITY 3 +#define ITEM_BATTERY 4 + +#define WEAPON_NONE 0 +#define WEAPON_CROWBAR 1 +#define WEAPON_GLOCK 2 +#define WEAPON_PYTHON 3 +#define WEAPON_MP5 4 +#define WEAPON_CHAINGUN 5 +#define WEAPON_CROSSBOW 6 +#define WEAPON_SHOTGUN 7 +#define WEAPON_RPG 8 +#define WEAPON_GAUSS 9 +#define WEAPON_EGON 10 +#define WEAPON_HORNETGUN 11 +#define WEAPON_HANDGRENADE 12 +#define WEAPON_TRIPMINE 13 +#define WEAPON_SATCHEL 14 +#define WEAPON_SNARK 15 + +#define WEAPON_ALLWEAPONS (~(1<absmin = pev->origin + Vector(-16, -16, -5); + pev->absmax = pev->origin + Vector(16, 16, 28); + } + + void PrimaryAttack( void ); + BOOL Deploy( void ); + void Holster( int skiplocal = 0 ); + void WeaponIdle( void ); + + virtual BOOL UseDecrement( void ) + { +#if defined( CLIENT_WEAPONS ) + return TRUE; +#else + return FALSE; +#endif + } + +private: + unsigned short m_usTripFire; + +}; + +class CSqueak : public CBasePlayerWeapon +{ +public: + void Spawn( void ); + void Precache( void ); + int iItemSlot( void ) { return 5; } + int GetItemInfo(ItemInfo *p); + + void PrimaryAttack( void ); + void SecondaryAttack( void ); + BOOL Deploy( void ); + void Holster( int skiplocal = 0 ); + void WeaponIdle( void ); + int m_fJustThrown; + + virtual BOOL UseDecrement( void ) + { +#if defined( CLIENT_WEAPONS ) + return TRUE; +#else + return FALSE; +#endif + } + +private: + unsigned short m_usSnarkFire; +}; + + +#endif // WEAPONS_H diff --git a/sdk/hlsdk/engine/Sequence.h b/sdk/hlsdk/engine/Sequence.h new file mode 100644 index 0000000..6253018 --- /dev/null +++ b/sdk/hlsdk/engine/Sequence.h @@ -0,0 +1,201 @@ +//--------------------------------------------------------------------------- +// +// S c r i p t e d S e q u e n c e s +// +//--------------------------------------------------------------------------- +#ifndef _INCLUDE_SEQUENCE_H_ +#define _INCLUDE_SEQUENCE_H_ + + +#ifndef _DEF_BYTE_ +typedef unsigned char byte; +#endif + +//--------------------------------------------------------------------------- +// client_textmessage_t +//--------------------------------------------------------------------------- +typedef struct client_textmessage_s +{ + int effect; + byte r1, g1, b1, a1; // 2 colors for effects + byte r2, g2, b2, a2; + float x; + float y; + float fadein; + float fadeout; + float holdtime; + float fxtime; + const char *pName; + const char *pMessage; +} client_textmessage_t; + + +//-------------------------------------------------------------------------- +// sequenceDefaultBits_e +// +// Enumerated list of possible modifiers for a command. This enumeration +// is used in a bitarray controlling what modifiers are specified for a command. +//--------------------------------------------------------------------------- +enum sequenceModifierBits +{ + SEQUENCE_MODIFIER_EFFECT_BIT = (1 << 1), + SEQUENCE_MODIFIER_POSITION_BIT = (1 << 2), + SEQUENCE_MODIFIER_COLOR_BIT = (1 << 3), + SEQUENCE_MODIFIER_COLOR2_BIT = (1 << 4), + SEQUENCE_MODIFIER_FADEIN_BIT = (1 << 5), + SEQUENCE_MODIFIER_FADEOUT_BIT = (1 << 6), + SEQUENCE_MODIFIER_HOLDTIME_BIT = (1 << 7), + SEQUENCE_MODIFIER_FXTIME_BIT = (1 << 8), + SEQUENCE_MODIFIER_SPEAKER_BIT = (1 << 9), + SEQUENCE_MODIFIER_LISTENER_BIT = (1 << 10), + SEQUENCE_MODIFIER_TEXTCHANNEL_BIT = (1 << 11), +}; +typedef enum sequenceModifierBits sequenceModifierBits_e ; + + +//--------------------------------------------------------------------------- +// sequenceCommandEnum_e +// +// Enumerated sequence command types. +//--------------------------------------------------------------------------- +enum sequenceCommandEnum_ +{ + SEQUENCE_COMMAND_ERROR = -1, + SEQUENCE_COMMAND_PAUSE = 0, + SEQUENCE_COMMAND_FIRETARGETS, + SEQUENCE_COMMAND_KILLTARGETS, + SEQUENCE_COMMAND_TEXT, + SEQUENCE_COMMAND_SOUND, + SEQUENCE_COMMAND_GOSUB, + SEQUENCE_COMMAND_SENTENCE, + SEQUENCE_COMMAND_REPEAT, + SEQUENCE_COMMAND_SETDEFAULTS, + SEQUENCE_COMMAND_MODIFIER, + SEQUENCE_COMMAND_POSTMODIFIER, + SEQUENCE_COMMAND_NOOP, + + SEQUENCE_MODIFIER_EFFECT, + SEQUENCE_MODIFIER_POSITION, + SEQUENCE_MODIFIER_COLOR, + SEQUENCE_MODIFIER_COLOR2, + SEQUENCE_MODIFIER_FADEIN, + SEQUENCE_MODIFIER_FADEOUT, + SEQUENCE_MODIFIER_HOLDTIME, + SEQUENCE_MODIFIER_FXTIME, + SEQUENCE_MODIFIER_SPEAKER, + SEQUENCE_MODIFIER_LISTENER, + SEQUENCE_MODIFIER_TEXTCHANNEL, +}; +typedef enum sequenceCommandEnum_ sequenceCommandEnum_e; + + +//--------------------------------------------------------------------------- +// sequenceCommandType_e +// +// Typeerated sequence command types. +//--------------------------------------------------------------------------- +enum sequenceCommandType_ +{ + SEQUENCE_TYPE_COMMAND, + SEQUENCE_TYPE_MODIFIER, +}; +typedef enum sequenceCommandType_ sequenceCommandType_e; + + +//--------------------------------------------------------------------------- +// sequenceCommandMapping_s +// +// A mapping of a command enumerated-value to its name. +//--------------------------------------------------------------------------- +typedef struct sequenceCommandMapping_ sequenceCommandMapping_s; +struct sequenceCommandMapping_ +{ + sequenceCommandEnum_e commandEnum; + const char* commandName; + sequenceCommandType_e commandType; +}; + + +//--------------------------------------------------------------------------- +// sequenceCommandLine_s +// +// Structure representing a single command (usually 1 line) from a +// .SEQ file entry. +//--------------------------------------------------------------------------- +typedef struct sequenceCommandLine_ sequenceCommandLine_s; +struct sequenceCommandLine_ +{ + int commandType; // Specifies the type of command + client_textmessage_t clientMessage; // Text HUD message struct + char* speakerName; // Targetname of speaking entity + char* listenerName; // Targetname of entity being spoken to + char* soundFileName; // Name of sound file to play + char* sentenceName; // Name of sentences.txt to play + char* fireTargetNames; // List of targetnames to fire + char* killTargetNames; // List of targetnames to remove + float delay; // Seconds 'till next command + int repeatCount; // If nonzero, reset execution pointer to top of block (N times, -1 = infinite) + int textChannel; // Display channel on which text message is sent + int modifierBitField; // Bit field to specify what clientmessage fields are valid + sequenceCommandLine_s* nextCommandLine; // Next command (linked list) +}; + + +//--------------------------------------------------------------------------- +// sequenceEntry_s +// +// Structure representing a single command (usually 1 line) from a +// .SEQ file entry. +//--------------------------------------------------------------------------- +typedef struct sequenceEntry_ sequenceEntry_s; +struct sequenceEntry_ +{ + char* fileName; // Name of sequence file without .SEQ extension + char* entryName; // Name of entry label in file + sequenceCommandLine_s* firstCommand; // Linked list of commands in entry + sequenceEntry_s* nextEntry; // Next loaded entry + qboolean isGlobal; // Is entry retained over level transitions? +}; + + + +//--------------------------------------------------------------------------- +// sentenceEntry_s +// Structure representing a single sentence of a group from a .SEQ +// file entry. Sentences are identical to entries in sentences.txt, but +// can be unique per level and are loaded/unloaded with the level. +//--------------------------------------------------------------------------- +typedef struct sentenceEntry_ sentenceEntry_s; +struct sentenceEntry_ +{ + char* data; // sentence data (ie "We have hostiles" ) + sentenceEntry_s* nextEntry; // Next loaded entry + qboolean isGlobal; // Is entry retained over level transitions? + unsigned int index; // this entry's position in the file. +}; + +//-------------------------------------------------------------------------- +// sentenceGroupEntry_s +// Structure representing a group of sentences found in a .SEQ file. +// A sentence group is defined by all sentences with the same name, ignoring +// the number at the end of the sentence name. Groups enable a sentence +// to be picked at random across a group. +//-------------------------------------------------------------------------- +typedef struct sentenceGroupEntry_ sentenceGroupEntry_s; +struct sentenceGroupEntry_ +{ + char* groupName; // name of the group (ie CT_ALERT ) + unsigned int numSentences; // number of sentences in group + sentenceEntry_s* firstSentence; // head of linked list of sentences in group + sentenceGroupEntry_s* nextEntry; // next loaded group +}; + +//--------------------------------------------------------------------------- +// Function declarations +//--------------------------------------------------------------------------- +sequenceEntry_s* SequenceGet( const char* fileName, const char* entryName ); +void Sequence_ParseFile( const char* fileName, qboolean isGlobal ); +void Sequence_OnLevelLoad( const char* mapName ); +sentenceEntry_s* SequencePickSentence( const char *groupName, int pickMethod, int *picked ); + +#endif /* _INCLUDE_SEQUENCE_H_ */ diff --git a/sdk/hlsdk/engine/anorms.h b/sdk/hlsdk/engine/anorms.h new file mode 100644 index 0000000..d147aea --- /dev/null +++ b/sdk/hlsdk/engine/anorms.h @@ -0,0 +1,177 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +{-0.525731, 0.000000, 0.850651}, +{-0.442863, 0.238856, 0.864188}, +{-0.295242, 0.000000, 0.955423}, +{-0.309017, 0.500000, 0.809017}, +{-0.162460, 0.262866, 0.951056}, +{0.000000, 0.000000, 1.000000}, +{0.000000, 0.850651, 0.525731}, +{-0.147621, 0.716567, 0.681718}, +{0.147621, 0.716567, 0.681718}, +{0.000000, 0.525731, 0.850651}, +{0.309017, 0.500000, 0.809017}, +{0.525731, 0.000000, 0.850651}, +{0.295242, 0.000000, 0.955423}, +{0.442863, 0.238856, 0.864188}, +{0.162460, 0.262866, 0.951056}, +{-0.681718, 0.147621, 0.716567}, +{-0.809017, 0.309017, 0.500000}, +{-0.587785, 0.425325, 0.688191}, +{-0.850651, 0.525731, 0.000000}, +{-0.864188, 0.442863, 0.238856}, +{-0.716567, 0.681718, 0.147621}, +{-0.688191, 0.587785, 0.425325}, +{-0.500000, 0.809017, 0.309017}, +{-0.238856, 0.864188, 0.442863}, +{-0.425325, 0.688191, 0.587785}, +{-0.716567, 0.681718, -0.147621}, +{-0.500000, 0.809017, -0.309017}, +{-0.525731, 0.850651, 0.000000}, +{0.000000, 0.850651, -0.525731}, +{-0.238856, 0.864188, -0.442863}, +{0.000000, 0.955423, -0.295242}, +{-0.262866, 0.951056, -0.162460}, +{0.000000, 1.000000, 0.000000}, +{0.000000, 0.955423, 0.295242}, +{-0.262866, 0.951056, 0.162460}, +{0.238856, 0.864188, 0.442863}, +{0.262866, 0.951056, 0.162460}, +{0.500000, 0.809017, 0.309017}, +{0.238856, 0.864188, -0.442863}, +{0.262866, 0.951056, -0.162460}, +{0.500000, 0.809017, -0.309017}, +{0.850651, 0.525731, 0.000000}, +{0.716567, 0.681718, 0.147621}, +{0.716567, 0.681718, -0.147621}, +{0.525731, 0.850651, 0.000000}, +{0.425325, 0.688191, 0.587785}, +{0.864188, 0.442863, 0.238856}, +{0.688191, 0.587785, 0.425325}, +{0.809017, 0.309017, 0.500000}, +{0.681718, 0.147621, 0.716567}, +{0.587785, 0.425325, 0.688191}, +{0.955423, 0.295242, 0.000000}, +{1.000000, 0.000000, 0.000000}, +{0.951056, 0.162460, 0.262866}, +{0.850651, -0.525731, 0.000000}, +{0.955423, -0.295242, 0.000000}, +{0.864188, -0.442863, 0.238856}, +{0.951056, -0.162460, 0.262866}, +{0.809017, -0.309017, 0.500000}, +{0.681718, -0.147621, 0.716567}, +{0.850651, 0.000000, 0.525731}, +{0.864188, 0.442863, -0.238856}, +{0.809017, 0.309017, -0.500000}, +{0.951056, 0.162460, -0.262866}, +{0.525731, 0.000000, -0.850651}, +{0.681718, 0.147621, -0.716567}, +{0.681718, -0.147621, -0.716567}, +{0.850651, 0.000000, -0.525731}, +{0.809017, -0.309017, -0.500000}, +{0.864188, -0.442863, -0.238856}, +{0.951056, -0.162460, -0.262866}, +{0.147621, 0.716567, -0.681718}, +{0.309017, 0.500000, -0.809017}, +{0.425325, 0.688191, -0.587785}, +{0.442863, 0.238856, -0.864188}, +{0.587785, 0.425325, -0.688191}, +{0.688191, 0.587785, -0.425325}, +{-0.147621, 0.716567, -0.681718}, +{-0.309017, 0.500000, -0.809017}, +{0.000000, 0.525731, -0.850651}, +{-0.525731, 0.000000, -0.850651}, +{-0.442863, 0.238856, -0.864188}, +{-0.295242, 0.000000, -0.955423}, +{-0.162460, 0.262866, -0.951056}, +{0.000000, 0.000000, -1.000000}, +{0.295242, 0.000000, -0.955423}, +{0.162460, 0.262866, -0.951056}, +{-0.442863, -0.238856, -0.864188}, +{-0.309017, -0.500000, -0.809017}, +{-0.162460, -0.262866, -0.951056}, +{0.000000, -0.850651, -0.525731}, +{-0.147621, -0.716567, -0.681718}, +{0.147621, -0.716567, -0.681718}, +{0.000000, -0.525731, -0.850651}, +{0.309017, -0.500000, -0.809017}, +{0.442863, -0.238856, -0.864188}, +{0.162460, -0.262866, -0.951056}, +{0.238856, -0.864188, -0.442863}, +{0.500000, -0.809017, -0.309017}, +{0.425325, -0.688191, -0.587785}, +{0.716567, -0.681718, -0.147621}, +{0.688191, -0.587785, -0.425325}, +{0.587785, -0.425325, -0.688191}, +{0.000000, -0.955423, -0.295242}, +{0.000000, -1.000000, 0.000000}, +{0.262866, -0.951056, -0.162460}, +{0.000000, -0.850651, 0.525731}, +{0.000000, -0.955423, 0.295242}, +{0.238856, -0.864188, 0.442863}, +{0.262866, -0.951056, 0.162460}, +{0.500000, -0.809017, 0.309017}, +{0.716567, -0.681718, 0.147621}, +{0.525731, -0.850651, 0.000000}, +{-0.238856, -0.864188, -0.442863}, +{-0.500000, -0.809017, -0.309017}, +{-0.262866, -0.951056, -0.162460}, +{-0.850651, -0.525731, 0.000000}, +{-0.716567, -0.681718, -0.147621}, +{-0.716567, -0.681718, 0.147621}, +{-0.525731, -0.850651, 0.000000}, +{-0.500000, -0.809017, 0.309017}, +{-0.238856, -0.864188, 0.442863}, +{-0.262866, -0.951056, 0.162460}, +{-0.864188, -0.442863, 0.238856}, +{-0.809017, -0.309017, 0.500000}, +{-0.688191, -0.587785, 0.425325}, +{-0.681718, -0.147621, 0.716567}, +{-0.442863, -0.238856, 0.864188}, +{-0.587785, -0.425325, 0.688191}, +{-0.309017, -0.500000, 0.809017}, +{-0.147621, -0.716567, 0.681718}, +{-0.425325, -0.688191, 0.587785}, +{-0.162460, -0.262866, 0.951056}, +{0.442863, -0.238856, 0.864188}, +{0.162460, -0.262866, 0.951056}, +{0.309017, -0.500000, 0.809017}, +{0.147621, -0.716567, 0.681718}, +{0.000000, -0.525731, 0.850651}, +{0.425325, -0.688191, 0.587785}, +{0.587785, -0.425325, 0.688191}, +{0.688191, -0.587785, 0.425325}, +{-0.955423, 0.295242, 0.000000}, +{-0.951056, 0.162460, 0.262866}, +{-1.000000, 0.000000, 0.000000}, +{-0.850651, 0.000000, 0.525731}, +{-0.955423, -0.295242, 0.000000}, +{-0.951056, -0.162460, 0.262866}, +{-0.864188, 0.442863, -0.238856}, +{-0.951056, 0.162460, -0.262866}, +{-0.809017, 0.309017, -0.500000}, +{-0.864188, -0.442863, -0.238856}, +{-0.951056, -0.162460, -0.262866}, +{-0.809017, -0.309017, -0.500000}, +{-0.681718, 0.147621, -0.716567}, +{-0.681718, -0.147621, -0.716567}, +{-0.850651, 0.000000, -0.525731}, +{-0.688191, 0.587785, -0.425325}, +{-0.587785, 0.425325, -0.688191}, +{-0.425325, 0.688191, -0.587785}, +{-0.425325, -0.688191, -0.587785}, +{-0.587785, -0.425325, -0.688191}, +{-0.688191, -0.587785, -0.425325}, diff --git a/sdk/hlsdk/engine/archtypes.h b/sdk/hlsdk/engine/archtypes.h new file mode 100644 index 0000000..3315135 --- /dev/null +++ b/sdk/hlsdk/engine/archtypes.h @@ -0,0 +1,41 @@ +// +// Word size dependent definitions +// DAL 1/03 +// +#ifndef ARCHTYPES_H +#define ARCHTYPES_H + +#ifdef __x86_64__ +#define X64BITS +#endif + +#if defined( _WIN32 ) && (! defined( __MINGW32__ )) + +typedef __int16 int16; +typedef unsigned __int16 uint16; +typedef __int32 int32; +typedef unsigned __int32 uint32; +typedef __int64 int64; +typedef unsigned __int64 uint64; +typedef __int32 intp; // intp is an integer that can accomodate a pointer +typedef unsigned __int32 uintp; // (ie, sizeof(intp) >= sizeof(int) && sizeof(intp) >= sizeof(void *) + +#else /* _WIN32 */ + +typedef short int16; +typedef unsigned short uint16; +typedef int int32; +typedef unsigned int uint32; +typedef long long int64; +typedef unsigned long long uint64; +#ifdef X64BITS +typedef long long intp; +typedef unsigned long long uintp; +#else +typedef int intp; +typedef unsigned int uintp; +#endif + +#endif /* else _WIN32 */ + +#endif /* ARCHTYPES_H */ diff --git a/sdk/hlsdk/engine/cdll_int.h b/sdk/hlsdk/engine/cdll_int.h new file mode 100644 index 0000000..18db1f7 --- /dev/null +++ b/sdk/hlsdk/engine/cdll_int.h @@ -0,0 +1,311 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// +// cdll_int.h +// +// 4-23-98 +// JOHN: client dll interface declarations +// + +#ifndef CDLL_INT_H +#define CDLL_INT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "const.h" + + +// this file is included by both the engine and the client-dll, +// so make sure engine declarations aren't done twice + +typedef int HSPRITE; // handle to a graphic + +#define SCRINFO_SCREENFLASH 1 +#define SCRINFO_STRETCHED 2 + +typedef struct SCREENINFO_s +{ + int iSize; + int iWidth; + int iHeight; + int iFlags; + int iCharHeight; + short charWidths[256]; +} SCREENINFO; + + +typedef struct client_data_s +{ + // fields that cannot be modified (ie. have no effect if changed) + vec3_t origin; + + // fields that can be changed by the cldll + vec3_t viewangles; + int iWeaponBits; + float fov; // field of view +} client_data_t; + +typedef struct client_sprite_s +{ + char szName[64]; + char szSprite[64]; + int hspr; + int iRes; + wrect_t rc; +} client_sprite_t; + +typedef struct client_textmessage_s +{ + int effect; + byte r1, g1, b1, a1; // 2 colors for effects + byte r2, g2, b2, a2; + float x; + float y; + float fadein; + float fadeout; + float holdtime; + float fxtime; + const char *pName; + const char *pMessage; +} client_textmessage_t; + +typedef struct hud_player_info_s +{ + char *name; + short ping; + byte thisplayer; // TRUE if this is the calling player + + // stuff that's unused at the moment, but should be done + byte spectator; + byte packetloss; + + char *model; + short topcolor; + short bottomcolor; + +} hud_player_info_t; + + +typedef struct cl_enginefuncs_s +{ + // sprite handlers + HSPRITE ( *pfnSPR_Load ) ( const char *szPicName ); + int ( *pfnSPR_Frames ) ( HSPRITE hPic ); + int ( *pfnSPR_Height ) ( HSPRITE hPic, int frame ); + int ( *pfnSPR_Width ) ( HSPRITE hPic, int frame ); + void ( *pfnSPR_Set ) ( HSPRITE hPic, int r, int g, int b ); + void ( *pfnSPR_Draw ) ( int frame, int x, int y, const wrect_t *prc ); + void ( *pfnSPR_DrawHoles ) ( int frame, int x, int y, const wrect_t *prc ); + void ( *pfnSPR_DrawAdditive ) ( int frame, int x, int y, const wrect_t *prc ); + void ( *pfnSPR_EnableScissor ) ( int x, int y, int width, int height ); + void ( *pfnSPR_DisableScissor ) ( void ); + client_sprite_t *( *pfnSPR_GetList ) ( char *psz, int *piCount ); + + // screen handlers + void ( *pfnFillRGBA ) ( int x, int y, int width, int height, int r, int g, int b, int a ); + int ( *pfnGetScreenInfo ) ( SCREENINFO *pscrinfo ); + void ( *pfnSetCrosshair ) ( HSPRITE hspr, wrect_t rc, int r, int g, int b ); + + // cvar handlers + struct cvar_s *( *pfnRegisterVariable ) ( char *szName, char *szValue, int flags ); + float ( *pfnGetCvarFloat ) ( char *szName ); + char* ( *pfnGetCvarString ) ( char *szName ); + + // command handlers + int ( *pfnAddCommand ) ( char *cmd_name, void (*function)(void) ); + int ( *pfnHookUserMsg ) ( char *szMsgName, pfnUserMsgHook pfn ); + int ( *pfnServerCmd ) ( char *szCmdString ); + int ( *pfnClientCmd ) ( char *szCmdString ); + + void ( *pfnGetPlayerInfo ) ( int ent_num, hud_player_info_t *pinfo ); + + // sound handlers + void ( *pfnPlaySoundByName ) ( char *szSound, float volume ); + void ( *pfnPlaySoundByIndex ) ( int iSound, float volume ); + + // vector helpers + void ( *pfnAngleVectors ) ( const float * vecAngles, float * forward, float * right, float * up ); + + // text message system + client_textmessage_t *( *pfnTextMessageGet ) ( const char *pName ); + int ( *pfnDrawCharacter ) ( int x, int y, int number, int r, int g, int b ); + int ( *pfnDrawConsoleString ) ( int x, int y, char *string ); + void ( *pfnDrawSetTextColor ) ( float r, float g, float b ); + void ( *pfnDrawConsoleStringLen )( const char *string, int *length, int *height ); + + void ( *pfnConsolePrint ) ( const char *string ); + void ( *pfnCenterPrint ) ( const char *string ); + + +// Added for user input processing + int ( *GetWindowCenterX ) ( void ); + int ( *GetWindowCenterY ) ( void ); + void ( *GetViewAngles ) ( float * ); + void ( *SetViewAngles ) ( float * ); + int ( *GetMaxClients ) ( void ); + void ( *Cvar_SetValue ) ( char *cvar, float value ); + + int (*Cmd_Argc) (void); + char *( *Cmd_Argv ) ( int arg ); + void ( *Con_Printf ) ( char *fmt, ... ); + void ( *Con_DPrintf ) ( char *fmt, ... ); + void ( *Con_NPrintf ) ( int pos, char *fmt, ... ); + void ( *Con_NXPrintf ) ( struct con_nprint_s *info, char *fmt, ... ); + + const char *( *PhysInfo_ValueForKey ) ( const char *key ); + const char *( *ServerInfo_ValueForKey )( const char *key ); + float ( *GetClientMaxspeed ) ( void ); + int ( *CheckParm ) ( char *parm, char **ppnext ); + void ( *Key_Event ) ( int key, int down ); + void ( *GetMousePosition ) ( int *mx, int *my ); + int ( *IsNoClipping ) ( void ); + + struct cl_entity_s *( *GetLocalPlayer ) ( void ); + struct cl_entity_s *( *GetViewModel ) ( void ); + struct cl_entity_s *( *GetEntityByIndex ) ( int idx ); + + float ( *GetClientTime ) ( void ); + void ( *V_CalcShake ) ( void ); + void ( *V_ApplyShake ) ( float *origin, float *angles, float factor ); + + int ( *PM_PointContents ) ( float *point, int *truecontents ); + int ( *PM_WaterEntity ) ( float *p ); + struct pmtrace_s *( *PM_TraceLine ) ( float *start, float *end, int flags, int usehull, int ignore_pe ); + + struct model_s *( *CL_LoadModel ) ( const char *modelname, int *index ); + int ( *CL_CreateVisibleEntity ) ( int type, struct cl_entity_s *ent ); + + const struct model_s * ( *GetSpritePointer ) ( HSPRITE hSprite ); + void ( *pfnPlaySoundByNameAtLocation ) ( char *szSound, float volume, float *origin ); + + unsigned short ( *pfnPrecacheEvent ) ( int type, const char* psz ); + void ( *pfnPlaybackEvent ) ( int flags, const struct edict_s *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); + void ( *pfnWeaponAnim ) ( int iAnim, int body ); + float ( *pfnRandomFloat ) ( float flLow, float flHigh ); + long ( *pfnRandomLong ) ( long lLow, long lHigh ); + void ( *pfnHookEvent ) ( char *name, void ( *pfnEvent )( struct event_args_s *args ) ); + int (*Con_IsVisible) (); + const char *( *pfnGetGameDirectory ) ( void ); + struct cvar_s *( *pfnGetCvarPointer ) ( const char *szName ); + const char *( *Key_LookupBinding ) ( const char *pBinding ); + const char *( *pfnGetLevelName ) ( void ); + void ( *pfnGetScreenFade ) ( struct screenfade_s *fade ); + void ( *pfnSetScreenFade ) ( struct screenfade_s *fade ); + void *( *VGui_GetPanel ) ( ); + void ( *VGui_ViewportPaintBackground ) (int extents[4]); + + byte* (*COM_LoadFile) ( char *path, int usehunk, int *pLength ); + char* (*COM_ParseFile) ( char *data, char *token ); + void (*COM_FreeFile) ( void *buffer ); + + struct triangleapi_s *pTriAPI; + struct efx_api_s *pEfxAPI; + struct event_api_s *pEventAPI; + struct demo_api_s *pDemoAPI; + struct net_api_s *pNetAPI; + struct IVoiceTweak_s *pVoiceTweak; + + // returns 1 if the client is a spectator only (connected to a proxy), 0 otherwise or 2 if in dev_overview mode + int ( *IsSpectateOnly ) ( void ); + struct model_s *( *LoadMapSprite ) ( const char *filename ); + + // file search functions + void ( *COM_AddAppDirectoryToSearchPath ) ( const char *pszBaseDir, const char *appName ); + int ( *COM_ExpandFilename) ( const char *fileName, char *nameOutBuffer, int nameOutBufferSize ); + + // User info + // playerNum is in the range (1, MaxClients) + // returns NULL if player doesn't exit + // returns "" if no value is set + const char *( *PlayerInfo_ValueForKey )( int playerNum, const char *key ); + void ( *PlayerInfo_SetValueForKey )( const char *key, const char *value ); + + // Gets a unique ID for the specified player. This is the same even if you see the player on a different server. + // iPlayer is an entity index, so client 0 would use iPlayer=1. + // Returns false if there is no player on the server in the specified slot. + qboolean (*GetPlayerUniqueID)(int iPlayer, char playerID[16]); + + // TrackerID access + int (*GetTrackerIDForPlayer)(int playerSlot); + int (*GetPlayerForTrackerID)(int trackerID); + + // Same as pfnServerCmd, but the message goes in the unreliable stream so it can't clog the net stream + // (but it might not get there). + int ( *pfnServerCmdUnreliable )( char *szCmdString ); + + void ( *pfnGetMousePos )( struct tagPOINT *ppt ); + void ( *pfnSetMousePos )( int x, int y ); + void ( *pfnSetMouseEnable )( qboolean fEnable ); +} cl_enginefunc_t; + +#ifndef IN_BUTTONS_H +#include "in_buttons.h" +#endif + +#define CLDLL_INTERFACE_VERSION 7 + +extern void ClientDLL_Init( void ); // from cdll_int.c +extern void ClientDLL_Shutdown( void ); +extern void ClientDLL_HudInit( void ); +extern void ClientDLL_HudVidInit( void ); +extern void ClientDLL_UpdateClientData( void ); +extern void ClientDLL_Frame( double time ); +extern void ClientDLL_HudRedraw( int intermission ); +extern void ClientDLL_MoveClient( struct playermove_s *ppmove ); +extern void ClientDLL_ClientMoveInit( struct playermove_s *ppmove ); +extern char ClientDLL_ClientTextureType( char *name ); + +extern void ClientDLL_CreateMove( float frametime, struct usercmd_s *cmd, int active ); +extern void ClientDLL_ActivateMouse( void ); +extern void ClientDLL_DeactivateMouse( void ); +extern void ClientDLL_MouseEvent( int mstate ); +extern void ClientDLL_ClearStates( void ); +extern int ClientDLL_IsThirdPerson( void ); +extern void ClientDLL_GetCameraOffsets( float *ofs ); +extern int ClientDLL_GraphKeyDown( void ); +extern struct kbutton_s *ClientDLL_FindKey( const char *name ); +extern void ClientDLL_CAM_Think( void ); +extern void ClientDLL_IN_Accumulate( void ); +extern void ClientDLL_CalcRefdef( struct ref_params_s *pparams ); +extern int ClientDLL_AddEntity( int type, struct cl_entity_s *ent ); +extern void ClientDLL_CreateEntities( void ); + +extern void ClientDLL_DrawNormalTriangles( void ); +extern void ClientDLL_DrawTransparentTriangles( void ); +extern void ClientDLL_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity ); +extern void ClientDLL_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed ); +extern void ClientDLL_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client ); +extern void ClientDLL_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src ); +extern void ClientDLL_TxferPredictionData ( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const struct weapon_data_s *pwd ); +extern void ClientDLL_ReadDemoBuffer( int size, unsigned char *buffer ); +extern int ClientDLL_ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); +extern int ClientDLL_GetHullBounds( int hullnumber, float *mins, float *maxs ); + +extern void ClientDLL_VGui_ConsolePrint(const char* text); + +extern int ClientDLL_Key_Event( int down, int keynum, const char *pszCurrentBinding ); +extern void ClientDLL_TempEntUpdate( double ft, double ct, double grav, struct tempent_s **ppFreeTE, struct tempent_s **ppActiveTE, int ( *addTEntity )( struct cl_entity_s *pEntity ), void ( *playTESound )( struct tempent_s *pTemp, float damp ) ); +extern struct cl_entity_s *ClientDLL_GetUserEntity( int index ); +extern void ClientDLL_VoiceStatus(int entindex, qboolean bTalking); +extern void ClientDLL_DirectorMessage( int iSize, void *pbuf ); + + +#ifdef __cplusplus +} +#endif + +#endif // CDLL_INT_H diff --git a/sdk/hlsdk/engine/custom.h b/sdk/hlsdk/engine/custom.h new file mode 100644 index 0000000..79030ef --- /dev/null +++ b/sdk/hlsdk/engine/custom.h @@ -0,0 +1,103 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// Customization.h + +#ifndef CUSTOM_H +#define CUSTOM_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +#include "const.h" + +#define MAX_QPATH 64 // Must match value in quakedefs.h + +///////////////// +// Customization +// passed to pfnPlayerCustomization +// For automatic downloading. +typedef enum +{ + t_sound = 0, + t_skin, + t_model, + t_decal, + t_generic, + t_eventscript, + t_world, // Fake type for world, is really t_model +} resourcetype_t; + + +typedef struct +{ + int size; +} _resourceinfo_t; + +typedef struct resourceinfo_s +{ + _resourceinfo_t info[ 8 ]; +} resourceinfo_t; + +#define RES_FATALIFMISSING (1<<0) // Disconnect if we can't get this file. +#define RES_WASMISSING (1<<1) // Do we have the file locally, did we get it ok? +#define RES_CUSTOM (1<<2) // Is this resource one that corresponds to another player's customization + // or is it a server startup resource. +#define RES_REQUESTED (1<<3) // Already requested a download of this one +#define RES_PRECACHED (1<<4) // Already precached + +#include "crc.h" + +typedef struct resource_s +{ + char szFileName[MAX_QPATH]; // File name to download/precache. + resourcetype_t type; // t_sound, t_skin, t_model, t_decal. + int nIndex; // For t_decals + int nDownloadSize; // Size in Bytes if this must be downloaded. + unsigned char ucFlags; + +// For handling client to client resource propagation + unsigned char rgucMD5_hash[16]; // To determine if we already have it. + unsigned char playernum; // Which player index this resource is associated with, if it's a custom resource. + + unsigned char rguc_reserved[ 32 ]; // For future expansion + struct resource_s *pNext; // Next in chain. + struct resource_s *pPrev; +} resource_t; + +typedef struct customization_s +{ + qboolean bInUse; // Is this customization in use; + resource_t resource; // The resource_t for this customization + qboolean bTranslated; // Has the raw data been translated into a useable format? + // (e.g., raw decal .wad make into texture_t *) + int nUserData1; // Customization specific data + int nUserData2; // Customization specific data + void *pInfo; // Buffer that holds the data structure that references the data (e.g., the cachewad_t) + void *pBuffer; // Buffer that holds the data for the customization (the raw .wad data) + struct customization_s *pNext; // Next in chain +} customization_t; + +#define FCUST_FROMHPAK ( 1<<0 ) +#define FCUST_WIPEDATA ( 1<<1 ) +#define FCUST_IGNOREINIT ( 1<<2 ) + +void COM_ClearCustomizationList( struct customization_s *pHead, qboolean bCleanDecals); +qboolean COM_CreateCustomization( struct customization_s *pListHead, struct resource_s *pResource, int playernumber, int flags, + struct customization_s **pCustomization, int *nLumps ); +int COM_SizeofResourceList ( struct resource_s *pList, struct resourceinfo_s *ri ); + +#endif // CUSTOM_H diff --git a/sdk/hlsdk/engine/customentity.h b/sdk/hlsdk/engine/customentity.h new file mode 100644 index 0000000..0895bee --- /dev/null +++ b/sdk/hlsdk/engine/customentity.h @@ -0,0 +1,38 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef CUSTOMENTITY_H +#define CUSTOMENTITY_H + +// Custom Entities + +// Start/End Entity is encoded as 12 bits of entity index, and 4 bits of attachment (4:12) +#define BEAMENT_ENTITY(x) ((x)&0xFFF) +#define BEAMENT_ATTACHMENT(x) (((x)>>12)&0xF) + +// Beam types, encoded as a byte +enum +{ + BEAM_POINTS = 0, + BEAM_ENTPOINT, + BEAM_ENTS, + BEAM_HOSE, +}; + +#define BEAM_FSINE 0x10 +#define BEAM_FSOLID 0x20 +#define BEAM_FSHADEIN 0x40 +#define BEAM_FSHADEOUT 0x80 + +#endif //CUSTOMENTITY_H diff --git a/sdk/hlsdk/engine/edict.h b/sdk/hlsdk/engine/edict.h new file mode 100644 index 0000000..cd55083 --- /dev/null +++ b/sdk/hlsdk/engine/edict.h @@ -0,0 +1,38 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#if !defined EDICT_H +#define EDICT_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif +#define MAX_ENT_LEAFS 48 + +#include "progdefs.h" + +struct edict_s +{ + qboolean free; // +4 + int serialnumber; // +4 + link_t area; // +8 linked to a division node or leaf + + int headnode; // -1 to use normal leaf check || *((int *)pthis + 4) + int num_leafs; + short leafnums[MAX_ENT_LEAFS]; + + float freetime; // sv.time when the object was freed + + void* pvPrivateData; // Alloced and freed by engine, used by DLLs + + entvars_t v; // C exported fields from progs + + // other fields from progs come immediately after +}; + +#endif diff --git a/sdk/hlsdk/engine/eiface.h b/sdk/hlsdk/engine/eiface.h new file mode 100644 index 0000000..d1409aa --- /dev/null +++ b/sdk/hlsdk/engine/eiface.h @@ -0,0 +1,528 @@ +/*** +* +* Copyright (c) 1999, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef EIFACE_H +#define EIFACE_H + +#include "archtypes.h" // DAL + +#ifdef HLDEMO_BUILD +#define INTERFACE_VERSION 001 +#else // !HLDEMO_BUILD, i.e., regular version of HL +#define INTERFACE_VERSION 140 +#endif // !HLDEMO_BUILD + +#include +#include "custom.h" +#include "cvardef.h" +#include "Sequence.h" +// +// Defines entity interface between engine and DLLs. +// This header file included by engine files and DLL files. +// +// Before including this header, DLLs must: +// include progdefs.h +// This is conveniently done for them in extdll.h +// + +#ifdef _WIN32 +#define DLLEXPORT __stdcall +#else +#define DLLEXPORT /* */ +#endif + +typedef enum + { + at_notice, + at_console, // same as at_notice, but forces a ConPrintf, not a message box + at_aiconsole, // same as at_console, but only shown if developer level is 2! + at_warning, + at_error, + at_logged // Server print to console ( only in multiplayer games ). + } ALERT_TYPE; + +// 4-22-98 JOHN: added for use in pfnClientPrintf +typedef enum + { + print_console, + print_center, + print_chat, + } PRINT_TYPE; + +// For integrity checking of content on clients +typedef enum +{ + force_exactfile, // File on client must exactly match server's file + force_model_samebounds, // For model files only, the geometry must fit in the same bbox + force_model_specifybounds, // For model files only, the geometry must fit in the specified bbox + force_model_specifybounds_if_avail, // For Steam model files only, the geometry must fit in the specified bbox (if the file is available) +} FORCE_TYPE; + +// Returned by TraceLine +typedef struct + { + int fAllSolid; // if true, plane is not valid + int fStartSolid; // if true, the initial point was in a solid area + int fInOpen; + int fInWater; + float flFraction; // time completed, 1.0 = didn't hit anything + vec3_t vecEndPos; // final position + float flPlaneDist; + vec3_t vecPlaneNormal; // surface normal at impact + edict_t *pHit; // entity the surface is on + int iHitgroup; // 0 == generic, non zero is specific body part + } TraceResult; + +// CD audio status +typedef struct +{ + int fPlaying;// is sound playing right now? + int fWasPlaying;// if not, CD is paused if WasPlaying is true. + int fInitialized; + int fEnabled; + int fPlayLooping; + float cdvolume; + //BYTE remap[100]; + int fCDRom; + int fPlayTrack; +} CDStatus; + +#include "../common/crc.h" + + +// Engine hands this to DLLs for functionality callbacks +typedef struct enginefuncs_s +{ + int (*pfnPrecacheModel) (char* s); + int (*pfnPrecacheSound) (char* s); + void (*pfnSetModel) (edict_t *e, const char *m); + int (*pfnModelIndex) (const char *m); + int (*pfnModelFrames) (int modelIndex); + void (*pfnSetSize) (edict_t *e, const float *rgflMin, const float *rgflMax); + void (*pfnChangeLevel) (char* s1, char* s2); + void (*pfnGetSpawnParms) (edict_t *ent); + void (*pfnSaveSpawnParms) (edict_t *ent); + float (*pfnVecToYaw) (const float *rgflVector); + void (*pfnVecToAngles) (const float *rgflVectorIn, float *rgflVectorOut); + void (*pfnMoveToOrigin) (edict_t *ent, const float *pflGoal, float dist, int iMoveType); + void (*pfnChangeYaw) (edict_t* ent); + void (*pfnChangePitch) (edict_t* ent); + edict_t* (*pfnFindEntityByString) (edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue); + int (*pfnGetEntityIllum) (edict_t* pEnt); + edict_t* (*pfnFindEntityInSphere) (edict_t *pEdictStartSearchAfter, const float *org, float rad); + edict_t* (*pfnFindClientInPVS) (edict_t *pEdict); + edict_t* (*pfnEntitiesInPVS) (edict_t *pplayer); + void (*pfnMakeVectors) (const float *rgflVector); + void (*pfnAngleVectors) (const float *rgflVector, float *forward, float *right, float *up); + edict_t* (*pfnCreateEntity) (void); + void (*pfnRemoveEntity) (edict_t* e); + edict_t* (*pfnCreateNamedEntity) (int className); + void (*pfnMakeStatic) (edict_t *ent); + int (*pfnEntIsOnFloor) (edict_t *e); + int (*pfnDropToFloor) (edict_t* e); + int (*pfnWalkMove) (edict_t *ent, float yaw, float dist, int iMode); + void (*pfnSetOrigin) (edict_t *e, const float *rgflOrigin); + void (*pfnEmitSound) (edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch); + void (*pfnEmitAmbientSound) (edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch); + void (*pfnTraceLine) (const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); + void (*pfnTraceToss) (edict_t* pent, edict_t* pentToIgnore, TraceResult *ptr); + int (*pfnTraceMonsterHull) (edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); + void (*pfnTraceHull) (const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr); + void (*pfnTraceModel) (const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr); + const char *(*pfnTraceTexture) (edict_t *pTextureEntity, const float *v1, const float *v2 ); + void (*pfnTraceSphere) (const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr); + void (*pfnGetAimVector) (edict_t* ent, float speed, float *rgflReturn); + void (*pfnServerCommand) (char* str); + void (*pfnServerExecute) (void); + void (*pfnClientCommand) (edict_t* pEdict, char* szFmt, ...); + void (*pfnParticleEffect) (const float *org, const float *dir, float color, float count); + void (*pfnLightStyle) (int style, char* val); + int (*pfnDecalIndex) (const char *name); + int (*pfnPointContents) (const float *rgflVector); + void (*pfnMessageBegin) (int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); + void (*pfnMessageEnd) (void); + void (*pfnWriteByte) (int iValue); + void (*pfnWriteChar) (int iValue); + void (*pfnWriteShort) (int iValue); + void (*pfnWriteLong) (int iValue); + void (*pfnWriteAngle) (float flValue); + void (*pfnWriteCoord) (float flValue); + void (*pfnWriteString) (const char *sz); + void (*pfnWriteEntity) (int iValue); + void (*pfnCVarRegister) (cvar_t *pCvar); + float (*pfnCVarGetFloat) (const char *szVarName); + const char* (*pfnCVarGetString) (const char *szVarName); + void (*pfnCVarSetFloat) (const char *szVarName, float flValue); + void (*pfnCVarSetString) (const char *szVarName, const char *szValue); + void (*pfnAlertMessage) (ALERT_TYPE atype, char *szFmt, ...); + void (*pfnEngineFprintf) (void *pfile, char *szFmt, ...); + void* (*pfnPvAllocEntPrivateData) (edict_t *pEdict, int32 cb); + void* (*pfnPvEntPrivateData) (edict_t *pEdict); + void (*pfnFreeEntPrivateData) (edict_t *pEdict); + const char* (*pfnSzFromIndex) (int iString); + int (*pfnAllocString) (const char *szValue); + struct entvars_s* (*pfnGetVarsOfEnt) (edict_t *pEdict); + edict_t* (*pfnPEntityOfEntOffset) (int iEntOffset); + int (*pfnEntOffsetOfPEntity) (const edict_t *pEdict); + int (*pfnIndexOfEdict) (const edict_t *pEdict); + edict_t* (*pfnPEntityOfEntIndex) (int iEntIndex); + edict_t* (*pfnFindEntityByVars) (struct entvars_s* pvars); + void* (*pfnGetModelPtr) (edict_t* pEdict); + int (*pfnRegUserMsg) (const char *pszName, int iSize); + void (*pfnAnimationAutomove) (const edict_t* pEdict, float flTime); + void (*pfnGetBonePosition) (const edict_t* pEdict, int iBone, float *rgflOrigin, float *rgflAngles ); + uint32 (*pfnFunctionFromName) ( const char *pName ); + const char *(*pfnNameForFunction) ( uint32 function ); + void (*pfnClientPrintf) ( edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg ); // JOHN: engine callbacks so game DLL can print messages to individual clients + void (*pfnServerPrint) ( const char *szMsg ); + const char *(*pfnCmd_Args) ( void ); // these 3 added + const char *(*pfnCmd_Argv) ( int argc ); // so game DLL can easily + int (*pfnCmd_Argc) ( void ); // access client 'cmd' strings + void (*pfnGetAttachment) (const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles ); + void (*pfnCRC32_Init) (CRC32_t *pulCRC); + void (*pfnCRC32_ProcessBuffer) (CRC32_t *pulCRC, void *p, int len); + void (*pfnCRC32_ProcessByte) (CRC32_t *pulCRC, unsigned char ch); + CRC32_t (*pfnCRC32_Final) (CRC32_t pulCRC); + int32 (*pfnRandomLong) (int32 lLow, int32 lHigh); + float (*pfnRandomFloat) (float flLow, float flHigh); + void (*pfnSetView) (const edict_t *pClient, const edict_t *pViewent ); + float (*pfnTime) ( void ); + void (*pfnCrosshairAngle) (const edict_t *pClient, float pitch, float yaw); + byte * (*pfnLoadFileForMe) (char *filename, int *pLength); + void (*pfnFreeFile) (void *buffer); + void (*pfnEndSection) (const char *pszSectionName); // trigger_endsection + int (*pfnCompareFileTime) (char *filename1, char *filename2, int *iCompare); + void (*pfnGetGameDir) (char *szGetGameDir); + void (*pfnCvar_RegisterVariable) (cvar_t *variable); + void (*pfnFadeClientVolume) (const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds); + void (*pfnSetClientMaxspeed) (const edict_t *pEdict, float fNewMaxspeed); + edict_t * (*pfnCreateFakeClient) (const char *netname); // returns NULL if fake client can't be created + void (*pfnRunPlayerMove) (edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec ); + int (*pfnNumberOfEntities) (void); + char* (*pfnGetInfoKeyBuffer) (edict_t *e); // passing in NULL gets the serverinfo + char* (*pfnInfoKeyValue) (char *infobuffer, char *key); + void (*pfnSetKeyValue) (char *infobuffer, char *key, char *value); + void (*pfnSetClientKeyValue) (int clientIndex, char *infobuffer, char *key, char *value); + int (*pfnIsMapValid) (char *filename); + void (*pfnStaticDecal) ( const float *origin, int decalIndex, int entityIndex, int modelIndex ); + int (*pfnPrecacheGeneric) (char* s); + int (*pfnGetPlayerUserId) (edict_t *e ); // returns the server assigned userid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients + void (*pfnBuildSoundMsg) (edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); + int (*pfnIsDedicatedServer) (void);// is this a dedicated server? + cvar_t *(*pfnCVarGetPointer) (const char *szVarName); + unsigned int (*pfnGetPlayerWONId) (edict_t *e); // returns the server assigned WONid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients + + // YWB 8/1/99 TFF Physics additions + void (*pfnInfo_RemoveKey) ( char *s, const char *key ); + const char *(*pfnGetPhysicsKeyValue) ( const edict_t *pClient, const char *key ); + void (*pfnSetPhysicsKeyValue) ( const edict_t *pClient, const char *key, const char *value ); + const char *(*pfnGetPhysicsInfoString) ( const edict_t *pClient ); + unsigned short (*pfnPrecacheEvent) ( int type, const char*psz ); + void (*pfnPlaybackEvent) ( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); + + unsigned char *(*pfnSetFatPVS) ( float *org ); + unsigned char *(*pfnSetFatPAS) ( float *org ); + + int (*pfnCheckVisibility ) ( const edict_t *entity, unsigned char *pset ); + + void (*pfnDeltaSetField) ( struct delta_s *pFields, const char *fieldname ); + void (*pfnDeltaUnsetField) ( struct delta_s *pFields, const char *fieldname ); + void (*pfnDeltaAddEncoder) ( char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) ); + int (*pfnGetCurrentPlayer) ( void ); + int (*pfnCanSkipPlayer) ( const edict_t *player ); + int (*pfnDeltaFindField) ( struct delta_s *pFields, const char *fieldname ); + void (*pfnDeltaSetFieldByIndex) ( struct delta_s *pFields, int fieldNumber ); + void (*pfnDeltaUnsetFieldByIndex)( struct delta_s *pFields, int fieldNumber ); + + void (*pfnSetGroupMask) ( int mask, int op ); + + int (*pfnCreateInstancedBaseline) ( int classname, struct entity_state_s *baseline ); + void (*pfnCvar_DirectSet) ( struct cvar_s *var, char *value ); + + // Forces the client and server to be running with the same version of the specified file + // ( e.g., a player model ). + // Calling this has no effect in single player + void (*pfnForceUnmodified) ( FORCE_TYPE type, float *mins, float *maxs, const char *filename ); + + void (*pfnGetPlayerStats) ( const edict_t *pClient, int *ping, int *packet_loss ); + + void (*pfnAddServerCommand) ( char *cmd_name, void (*function) (void) ); + + // For voice communications, set which clients hear eachother. + // NOTE: these functions take player entity indices (starting at 1). + qboolean (*pfnVoice_GetClientListening)(int iReceiver, int iSender); + qboolean (*pfnVoice_SetClientListening)(int iReceiver, int iSender, qboolean bListen); + + const char *(*pfnGetPlayerAuthId) ( edict_t *e ); + + // PSV: Added for CZ training map +// const char *(*pfnKeyNameForBinding) ( const char* pBinding ); + + sequenceEntry_s* (*pfnSequenceGet) ( const char* fileName, const char* entryName ); + sentenceEntry_s* (*pfnSequencePickSentence) ( const char* groupName, int pickMethod, int *picked ); + + // LH: Give access to filesize via filesystem + int (*pfnGetFileSize) ( char *filename ); + + unsigned int (*pfnGetApproxWavePlayLen) (const char *filepath); + // MDC: Added for CZ career-mode + int (*pfnIsCareerMatch) ( void ); + + // BGC: return the number of characters of the localized string referenced by using "label" + int (*pfnGetLocalizedStringLength) (const char *label); + + // BGC: added to facilitate persistent storage of tutor message decay values for + // different career game profiles. Also needs to persist regardless of mp.dll being + // destroyed and recreated. + void (*pfnRegisterTutorMessageShown) (int mid); + int (*pfnGetTimesTutorMessageShown) (int mid); + void (*pfnProcessTutorMessageDecayBuffer) (int *buffer, int bufferLength); + void (*pfnConstructTutorMessageDecayBuffer) (int *buffer, int bufferLength); + void (*pfnResetTutorMessageDecayData) ( void ); + void (*pfnQueryClientCvarValue) ( const edict_t *player, const char *cvarName ); + void (*pfnQueryClientCvarValue2) ( const edict_t *player, const char *cvarName, int requestID ); +} enginefuncs_t; + + +// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 138 + +// Passed to pfnKeyValue +typedef struct KeyValueData_s +{ + char *szClassName; // in: entity classname + char *szKeyName; // in: name of key + char *szValue; // in: value of key + int32 fHandled; // out: DLL sets to true if key-value pair was understood +} KeyValueData; + + +typedef struct +{ + char mapName[ 32 ]; + char landmarkName[ 32 ]; + edict_t *pentLandmark; + vec3_t vecLandmarkOrigin; +} LEVELLIST; +#define MAX_LEVEL_CONNECTIONS 16 // These are encoded in the lower 16bits of ENTITYTABLE->flags + +typedef struct +{ + int id; // Ordinal ID of this entity (used for entity <--> pointer conversions) + edict_t *pent; // Pointer to the in-game entity + + int location; // Offset from the base data of this entity + int size; // Byte size of this entity's data + int flags; // This could be a short -- bit mask of transitions that this entity is in the PVS of + string_t classname; // entity class name + +} ENTITYTABLE; + +#define FENTTABLE_PLAYER 0x80000000 +#define FENTTABLE_REMOVED 0x40000000 +#define FENTTABLE_MOVEABLE 0x20000000 +#define FENTTABLE_GLOBAL 0x10000000 + +typedef struct saverestore_s SAVERESTOREDATA; + +#ifdef _WIN32 +typedef +#endif +struct saverestore_s +{ + char *pBaseData; // Start of all entity save data + char *pCurrentData; // Current buffer pointer for sequential access + int size; // Current data size + int bufferSize; // Total space for data + int tokenSize; // Size of the linear list of tokens + int tokenCount; // Number of elements in the pTokens table + char **pTokens; // Hash table of entity strings (sparse) + int currentIndex; // Holds a global entity table ID + int tableCount; // Number of elements in the entity table + int connectionCount;// Number of elements in the levelList[] + ENTITYTABLE *pTable; // Array of ENTITYTABLE elements (1 for each entity) + LEVELLIST levelList[ MAX_LEVEL_CONNECTIONS ]; // List of connections from this level + + // smooth transition + int fUseLandmark; + char szLandmarkName[20];// landmark we'll spawn near in next level + vec3_t vecLandmarkOffset;// for landmark transitions + float time; + char szCurrentMapName[32]; // To check global entities + +} +#ifdef _WIN32 +SAVERESTOREDATA +#endif +; + +typedef enum _fieldtypes +{ + FIELD_FLOAT = 0, // Any floating point value + FIELD_STRING, // A string ID (return from ALLOC_STRING) + FIELD_ENTITY, // An entity offset (EOFFSET) + FIELD_CLASSPTR, // CBaseEntity * + FIELD_EHANDLE, // Entity handle + FIELD_EVARS, // EVARS * + FIELD_EDICT, // edict_t *, or edict_t * (same thing) + FIELD_VECTOR, // Any vector + FIELD_POSITION_VECTOR, // A world coordinate (these are fixed up across level transitions automagically) + FIELD_POINTER, // Arbitrary data pointer... to be removed, use an array of FIELD_CHARACTER + FIELD_INTEGER, // Any integer or enum + FIELD_FUNCTION, // A class function pointer (Think, Use, etc) + FIELD_BOOLEAN, // boolean, implemented as an int, I may use this as a hint for compression + FIELD_SHORT, // 2 byte integer + FIELD_CHARACTER, // a byte + FIELD_TIME, // a floating point time (these are fixed up automatically too!) + FIELD_MODELNAME, // Engine string that is a model name (needs precache) + FIELD_SOUNDNAME, // Engine string that is a sound name (needs precache) + + FIELD_TYPECOUNT, // MUST BE LAST +} FIELDTYPE; + +#ifndef offsetof +#define offsetof(s,m) (size_t)&(((s *)0)->m) +#endif + +#define _FIELD(type,name,fieldtype,count,flags) { fieldtype, #name, offsetof(type, name), count, flags } +#define DEFINE_FIELD(type,name,fieldtype) _FIELD(type, name, fieldtype, 1, 0) +#define DEFINE_ARRAY(type,name,fieldtype,count) _FIELD(type, name, fieldtype, count, 0) +#define DEFINE_ENTITY_FIELD(name,fieldtype) _FIELD(entvars_t, name, fieldtype, 1, 0 ) +#define DEFINE_ENTITY_GLOBAL_FIELD(name,fieldtype) _FIELD(entvars_t, name, fieldtype, 1, FTYPEDESC_GLOBAL ) +#define DEFINE_GLOBAL_FIELD(type,name,fieldtype) _FIELD(type, name, fieldtype, 1, FTYPEDESC_GLOBAL ) + + +#define FTYPEDESC_GLOBAL 0x0001 // This field is masked for global entity save/restore + +typedef struct +{ + FIELDTYPE fieldType; + char *fieldName; + int fieldOffset; + short fieldSize; + short flags; +} TYPEDESCRIPTION; + +#define HLARRAYSIZE(p) (sizeof(p)/sizeof(p[0])) + +typedef struct +{ + // Initialize/shutdown the game (one-time call after loading of game .dll ) + void (*pfnGameInit) ( void ); + int (*pfnSpawn) ( edict_t *pent ); + void (*pfnThink) ( edict_t *pent ); + void (*pfnUse) ( edict_t *pentUsed, edict_t *pentOther ); + void (*pfnTouch) ( edict_t *pentTouched, edict_t *pentOther ); + void (*pfnBlocked) ( edict_t *pentBlocked, edict_t *pentOther ); + void (*pfnKeyValue) ( edict_t *pentKeyvalue, KeyValueData *pkvd ); + void (*pfnSave) ( edict_t *pent, SAVERESTOREDATA *pSaveData ); + int (*pfnRestore) ( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity ); + void (*pfnSetAbsBox) ( edict_t *pent ); + + void (*pfnSaveWriteFields) ( SAVERESTOREDATA *, const char *, void *, TYPEDESCRIPTION *, int ); + void (*pfnSaveReadFields) ( SAVERESTOREDATA *, const char *, void *, TYPEDESCRIPTION *, int ); + + void (*pfnSaveGlobalState) ( SAVERESTOREDATA * ); + void (*pfnRestoreGlobalState) ( SAVERESTOREDATA * ); + void (*pfnResetGlobalState) ( void ); + + qboolean (*pfnClientConnect) ( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); + + void (*pfnClientDisconnect) ( edict_t *pEntity ); + void (*pfnClientKill) ( edict_t *pEntity ); + void (*pfnClientPutInServer) ( edict_t *pEntity ); + void (*pfnClientCommand) ( edict_t *pEntity ); + void (*pfnClientUserInfoChanged)( edict_t *pEntity, char *infobuffer ); + + void (*pfnServerActivate) ( edict_t *pEdictList, int edictCount, int clientMax ); + void (*pfnServerDeactivate) ( void ); + + void (*pfnPlayerPreThink) ( edict_t *pEntity ); + void (*pfnPlayerPostThink) ( edict_t *pEntity ); + + void (*pfnStartFrame) ( void ); + void (*pfnParmsNewLevel) ( void ); + void (*pfnParmsChangeLevel) ( void ); + + // Returns string describing current .dll. E.g., TeamFotrress 2, Half-Life + const char *(*pfnGetGameDescription)( void ); + + // Notify dll about a player customization. + void (*pfnPlayerCustomization) ( edict_t *pEntity, customization_t *pCustom ); + + // Spectator funcs + void (*pfnSpectatorConnect) ( edict_t *pEntity ); + void (*pfnSpectatorDisconnect) ( edict_t *pEntity ); + void (*pfnSpectatorThink) ( edict_t *pEntity ); + + // Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint. + void (*pfnSys_Error) ( const char *error_string ); + + void (*pfnPM_Move) ( struct playermove_s *ppmove, qboolean server ); + void (*pfnPM_Init) ( struct playermove_s *ppmove ); + char (*pfnPM_FindTextureType)( char *name ); + void (*pfnSetupVisibility)( struct edict_s *pViewEntity, struct edict_s *pClient, unsigned char **pvs, unsigned char **pas ); + void (*pfnUpdateClientData) ( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd ); + int (*pfnAddToFullPack)( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet ); + void (*pfnCreateBaseline) ( int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs ); + void (*pfnRegisterEncoders) ( void ); + int (*pfnGetWeaponData) ( struct edict_s *player, struct weapon_data_s *info ); + + void (*pfnCmdStart) ( const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed ); + void (*pfnCmdEnd) ( const edict_t *player ); + + // Return 1 if the packet is valid. Set response_buffer_size if you want to send a response packet. Incoming, it holds the max + // size of the response_buffer, so you must zero it out if you choose not to respond. + int (*pfnConnectionlessPacket ) ( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); + + // Enumerates player hulls. Returns 0 if the hull number doesn't exist, 1 otherwise + int (*pfnGetHullBounds) ( int hullnumber, float *mins, float *maxs ); + + // Create baselines for certain "unplaced" items. + void (*pfnCreateInstancedBaselines) ( void ); + + // One of the pfnForceUnmodified files failed the consistency check for the specified player + // Return 0 to allow the client to continue, 1 to force immediate disconnection ( with an optional disconnect message of up to 256 characters ) + int (*pfnInconsistentFile)( const struct edict_s *player, const char *filename, char *disconnect_message ); + + // The game .dll should return 1 if lag compensation should be allowed ( could also just set + // the sv_unlag cvar. + // Most games right now should return 0, until client-side weapon prediction code is written + // and tested for them. + int (*pfnAllowLagCompensation)( void ); +} DLL_FUNCTIONS; + +extern DLL_FUNCTIONS gEntityInterface; + +// Current version. +#define NEW_DLL_FUNCTIONS_VERSION 1 + +typedef struct +{ + // Called right before the object's memory is freed. + // Calls its destructor. + void (*pfnOnFreeEntPrivateData)(edict_t *pEnt); + void (*pfnGameShutdown)(void); + int (*pfnShouldCollide)( edict_t *pentTouched, edict_t *pentOther ); + void (*pfnCvarValue)( const edict_t *pEnt, const char *value ); + void (*pfnCvarValue2)( const edict_t *pEnt, int requestID, const char *cvarName, const char *value ); +} NEW_DLL_FUNCTIONS; +typedef int (*NEW_DLL_FUNCTIONS_FN)( NEW_DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ); + +// Pointers will be null if the game DLL doesn't support this API. +extern NEW_DLL_FUNCTIONS gNewDLLFunctions; + +typedef int (*APIFUNCTION)( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ); +typedef int (*APIFUNCTION2)( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ); + +#endif /* EIFACE_H */ diff --git a/sdk/hlsdk/engine/keydefs.h b/sdk/hlsdk/engine/keydefs.h new file mode 100644 index 0000000..ef9b2fc --- /dev/null +++ b/sdk/hlsdk/engine/keydefs.h @@ -0,0 +1,131 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +// keydefs.h +#ifndef KEYDEFS_H +#define KEYDEFS_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +// +// these are the key numbers that should be passed to Key_Event +// +#define K_TAB 9 +#define K_ENTER 13 +#define K_ESCAPE 27 +#define K_SPACE 32 + +// normal keys should be passed as lowercased ascii + +#define K_BACKSPACE 127 +#define K_UPARROW 128 +#define K_DOWNARROW 129 +#define K_LEFTARROW 130 +#define K_RIGHTARROW 131 + +#define K_ALT 132 +#define K_CTRL 133 +#define K_SHIFT 134 +#define K_F1 135 +#define K_F2 136 +#define K_F3 137 +#define K_F4 138 +#define K_F5 139 +#define K_F6 140 +#define K_F7 141 +#define K_F8 142 +#define K_F9 143 +#define K_F10 144 +#define K_F11 145 +#define K_F12 146 +#define K_INS 147 +#define K_DEL 148 +#define K_PGDN 149 +#define K_PGUP 150 +#define K_HOME 151 +#define K_END 152 + +#define K_KP_HOME 160 +#define K_KP_UPARROW 161 +#define K_KP_PGUP 162 +#define K_KP_LEFTARROW 163 +#define K_KP_5 164 +#define K_KP_RIGHTARROW 165 +#define K_KP_END 166 +#define K_KP_DOWNARROW 167 +#define K_KP_PGDN 168 +#define K_KP_ENTER 169 +#define K_KP_INS 170 +#define K_KP_DEL 171 +#define K_KP_SLASH 172 +#define K_KP_MINUS 173 +#define K_KP_PLUS 174 +#define K_CAPSLOCK 175 + + +// +// joystick buttons +// +#define K_JOY1 203 +#define K_JOY2 204 +#define K_JOY3 205 +#define K_JOY4 206 + +// +// aux keys are for multi-buttoned joysticks to generate so they can use +// the normal binding process +// +#define K_AUX1 207 +#define K_AUX2 208 +#define K_AUX3 209 +#define K_AUX4 210 +#define K_AUX5 211 +#define K_AUX6 212 +#define K_AUX7 213 +#define K_AUX8 214 +#define K_AUX9 215 +#define K_AUX10 216 +#define K_AUX11 217 +#define K_AUX12 218 +#define K_AUX13 219 +#define K_AUX14 220 +#define K_AUX15 221 +#define K_AUX16 222 +#define K_AUX17 223 +#define K_AUX18 224 +#define K_AUX19 225 +#define K_AUX20 226 +#define K_AUX21 227 +#define K_AUX22 228 +#define K_AUX23 229 +#define K_AUX24 230 +#define K_AUX25 231 +#define K_AUX26 232 +#define K_AUX27 233 +#define K_AUX28 234 +#define K_AUX29 235 +#define K_AUX30 236 +#define K_AUX31 237 +#define K_AUX32 238 +#define K_MWHEELDOWN 239 +#define K_MWHEELUP 240 + +#define K_PAUSE 255 + +// +// mouse buttons generate virtual keys +// +#define K_MOUSE1 241 +#define K_MOUSE2 242 +#define K_MOUSE3 243 +#define K_MOUSE4 244 +#define K_MOUSE5 245 + +#endif // KEYDEFS_H diff --git a/sdk/hlsdk/engine/progdefs.h b/sdk/hlsdk/engine/progdefs.h new file mode 100644 index 0000000..c7b9855 --- /dev/null +++ b/sdk/hlsdk/engine/progdefs.h @@ -0,0 +1,226 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef PROGDEFS_H +#define PROGDEFS_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +typedef struct +{ + float time; + float frametime; + float force_retouch; + string_t mapname; + string_t startspot; + float deathmatch; + float coop; + float teamplay; + float serverflags; + float found_secrets; + vec3_t v_forward; + vec3_t v_up; + vec3_t v_right; + float trace_allsolid; + float trace_startsolid; + float trace_fraction; + vec3_t trace_endpos; + vec3_t trace_plane_normal; + float trace_plane_dist; + edict_t *trace_ent; + float trace_inopen; + float trace_inwater; + int trace_hitgroup; + int trace_flags; + int msg_entity; + int cdAudioTrack; + int maxClients; + int maxEntities; + const char *pStringBase; + + void *pSaveData; + vec3_t vecLandmarkOffset; +} globalvars_t; + + +typedef struct entvars_s +{ + string_t classname; + string_t globalname; + + vec3_t origin; + vec3_t oldorigin; + vec3_t velocity; + vec3_t basevelocity; + vec3_t clbasevelocity; // Base velocity that was passed in to server physics so + // client can predict conveyors correctly. Server zeroes it, so we need to store here, too. + vec3_t movedir; + + vec3_t angles; // Model angles + vec3_t avelocity; // angle velocity (degrees per second) + vec3_t punchangle; // auto-decaying view angle adjustment + vec3_t v_angle; // Viewing angle (player only) + + // For parametric entities + vec3_t endpos; + vec3_t startpos; + float impacttime; + float starttime; + + int fixangle; // 0:nothing, 1:force view angles, 2:add avelocity + float idealpitch; + float pitch_speed; + float ideal_yaw; + float yaw_speed; + + int modelindex; + string_t model; + + int viewmodel; // player's viewmodel + int weaponmodel; // what other players see + + vec3_t absmin; // BB max translated to world coord + vec3_t absmax; // BB max translated to world coord + vec3_t mins; // local BB min + vec3_t maxs; // local BB max + vec3_t size; // maxs - mins + + float ltime; + float nextthink; + + int movetype; + int solid; + + int skin; + int body; // sub-model selection for studiomodels + int effects; + + float gravity; // % of "normal" gravity + float friction; // inverse elasticity of MOVETYPE_BOUNCE + + int light_level; + + int sequence; // animation sequence + int gaitsequence; // movement animation sequence for player (0 for none) + float frame; // % playback position in animation sequences (0..255) + float animtime; // world time when frame was set + float framerate; // animation playback rate (-8x to 8x) + byte controller[4]; // bone controller setting (0..255) + byte blending[2]; // blending amount between sub-sequences (0..255) + + float scale; // sprite rendering scale (0..255) + + int rendermode; + float renderamt; + vec3_t rendercolor; + int renderfx; + + float health; + float frags; + int weapons; // bit mask for available weapons + float takedamage; + + int deadflag; + vec3_t view_ofs; // eye position + + int button; + int impulse; + + edict_t *chain; // Entity pointer when linked into a linked list + edict_t *dmg_inflictor; + edict_t *enemy; + edict_t *aiment; // entity pointer when MOVETYPE_FOLLOW + edict_t *owner; + edict_t *groundentity; + + int spawnflags; + int flags; + + int colormap; // lowbyte topcolor, highbyte bottomcolor + int team; + + float max_health; + float teleport_time; + float armortype; + float armorvalue; + int waterlevel; + int watertype; + + string_t target; + string_t targetname; + string_t netname; + string_t message; + + float dmg_take; + float dmg_save; + float dmg; + float dmgtime; + + string_t noise; + string_t noise1; + string_t noise2; + string_t noise3; + + float speed; + float air_finished; + float pain_finished; + float radsuit_finished; + + edict_t *pContainingEntity; + + int playerclass; + float maxspeed; + + float fov; + int weaponanim; + + int pushmsec; + + int bInDuck; + int flTimeStepSound; + int flSwimTime; + int flDuckTime; + int iStepLeft; + float flFallVelocity; + + int gamestate; + + int oldbuttons; + + int groupinfo; + + // For mods + int iuser1; + int iuser2; + int iuser3; + int iuser4; + float fuser1; + float fuser2; + float fuser3; + float fuser4; + vec3_t vuser1; + vec3_t vuser2; + vec3_t vuser3; + vec3_t vuser4; + edict_t *euser1; + edict_t *euser2; + edict_t *euser3; + edict_t *euser4; +} entvars_t; + + +#endif // PROGDEFS_H diff --git a/sdk/hlsdk/engine/progs.h b/sdk/hlsdk/engine/progs.h new file mode 100644 index 0000000..fe4796e --- /dev/null +++ b/sdk/hlsdk/engine/progs.h @@ -0,0 +1,82 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef PROGS_H +#define PROGS_H + +#include "progdefs.h" + +// 16 simultaneous events, max +#define MAX_EVENT_QUEUE 64 + +#define DEFAULT_EVENT_RESENDS 1 + +#include "event_flags.h" + +typedef struct event_info_s event_info_t; + +#include "event_args.h" + +struct event_info_s +{ + unsigned short index; // 0 implies not in use + + short packet_index; // Use data from state info for entity in delta_packet . -1 implies separate info based on event + // parameter signature + short entity_index; // The edict this event is associated with + + float fire_time; // if non-zero, the time when the event should be fired ( fixed up on the client ) + + event_args_t args; + +// CLIENT ONLY + int flags; // Reliable or not, etc. + +}; + +typedef struct event_state_s event_state_t; + +struct event_state_s +{ + struct event_info_s ei[ MAX_EVENT_QUEUE ]; +}; + +#if !defined( ENTITY_STATEH ) +#include "entity_state.h" +#endif + +#if !defined( EDICT_H ) +#include "edict.h" +#endif + +#define STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - (int)&(((t *)0)->m))) +#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area) + +//============================================================================ + +extern char *pr_strings; +extern globalvars_t gGlobalVariables; + +//============================================================================ + +edict_t *ED_Alloc (void); +void ED_Free (edict_t *ed); +void ED_LoadFromFile (char *data); + +edict_t *EDICT_NUM(int n); +int NUM_FOR_EDICT(const edict_t *e); + +#define PROG_TO_EDICT(e) ((edict_t *)((byte *)sv.edicts + e)) + +#endif // PROGS_H diff --git a/sdk/hlsdk/engine/shake.h b/sdk/hlsdk/engine/shake.h new file mode 100644 index 0000000..a18ddc2 --- /dev/null +++ b/sdk/hlsdk/engine/shake.h @@ -0,0 +1,55 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef SHAKE_H +#define SHAKE_H + +// Screen / View effects + +// screen shake +extern int gmsgShake; + +// This structure is sent over the net to describe a screen shake event +typedef struct +{ + unsigned short amplitude; // FIXED 4.12 amount of shake + unsigned short duration; // FIXED 4.12 seconds duration + unsigned short frequency; // FIXED 8.8 noise frequency (low frequency is a jerk,high frequency is a rumble) +} ScreenShake; + +extern void V_ApplyShake( float *origin, float *angles, float factor ); +extern void V_CalcShake( void ); +extern int V_ScreenShake( const char *pszName, int iSize, void *pbuf ); +extern int V_ScreenFade( const char *pszName, int iSize, void *pbuf ); + + +// Fade in/out +extern int gmsgFade; + +#define FFADE_IN 0x0000 // Just here so we don't pass 0 into the function +#define FFADE_OUT 0x0001 // Fade out (not in) +#define FFADE_MODULATE 0x0002 // Modulate (don't blend) +#define FFADE_STAYOUT 0x0004 // ignores the duration, stays faded out until new ScreenFade message received + +// This structure is sent over the net to describe a screen fade event +typedef struct +{ + unsigned short duration; // FIXED 4.12 seconds duration + unsigned short holdTime; // FIXED 4.12 seconds duration until reset (fade & hold) + short fadeFlags; // flags + byte r, g, b, a; // fade to color ( max alpha ) +} ScreenFade; + +#endif // SHAKE_H + diff --git a/sdk/hlsdk/engine/studio.h b/sdk/hlsdk/engine/studio.h new file mode 100644 index 0000000..ec98f2d --- /dev/null +++ b/sdk/hlsdk/engine/studio.h @@ -0,0 +1,362 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + + + + +#ifndef _STUDIO_H_ +#define _STUDIO_H_ + +/* +============================================================================== + +STUDIO MODELS + +Studio models are position independent, so the cache manager can move them. +============================================================================== +*/ + + +#define MAXSTUDIOTRIANGLES 20000 // TODO: tune this +#define MAXSTUDIOVERTS 2048 // TODO: tune this +#define MAXSTUDIOSEQUENCES 256 // total animation sequences +#define MAXSTUDIOSKINS 100 // total textures +#define MAXSTUDIOSRCBONES 512 // bones allowed at source movement +#define MAXSTUDIOBONES 128 // total bones actually used +#define MAXSTUDIOMODELS 32 // sub-models per model +#define MAXSTUDIOBODYPARTS 32 +#define MAXSTUDIOGROUPS 16 +#define MAXSTUDIOANIMATIONS 512 // per sequence +#define MAXSTUDIOMESHES 256 +#define MAXSTUDIOEVENTS 1024 +#define MAXSTUDIOPIVOTS 256 +#define MAXSTUDIOCONTROLLERS 8 + +typedef struct +{ + int id; + int version; + + char name[64]; + int length; + + vec3_t eyeposition; // ideal eye position + vec3_t min; // ideal movement hull size + vec3_t max; + + vec3_t bbmin; // clipping bounding box + vec3_t bbmax; + + int flags; + + int numbones; // bones + int boneindex; + + int numbonecontrollers; // bone controllers + int bonecontrollerindex; + + int numhitboxes; // complex bounding boxes + int hitboxindex; + + int numseq; // animation sequences + int seqindex; + + int numseqgroups; // demand loaded sequences + int seqgroupindex; + + int numtextures; // raw textures + int textureindex; + int texturedataindex; + + int numskinref; // replaceable textures + int numskinfamilies; + int skinindex; + + int numbodyparts; + int bodypartindex; + + int numattachments; // queryable attachable points + int attachmentindex; + + int soundtable; + int soundindex; + int soundgroups; + int soundgroupindex; + + int numtransitions; // animation node to animation node transition graph + int transitionindex; +} studiohdr_t; + +// header for demand loaded sequence group data +typedef struct +{ + int id; + int version; + + char name[64]; + int length; +} studioseqhdr_t; + +// bones +typedef struct +{ + char name[32]; // bone name for symbolic links + int parent; // parent bone + int flags; // ?? + int bonecontroller[6]; // bone controller index, -1 == none + float value[6]; // default DoF values + float scale[6]; // scale for delta DoF values +} mstudiobone_t; + + +// bone controllers +typedef struct +{ + int bone; // -1 == 0 + int type; // X, Y, Z, XR, YR, ZR, M + float start; + float end; + int rest; // byte index value at rest + int index; // 0-3 user set controller, 4 mouth +} mstudiobonecontroller_t; + +// intersection boxes +typedef struct +{ + int bone; + int group; // intersection group + vec3_t bbmin; // bounding box + vec3_t bbmax; +} mstudiobbox_t; + +#if !defined( CACHE_USER ) && !defined( QUAKEDEF_H ) +#define CACHE_USER +typedef struct cache_user_s +{ + void *data; +} cache_user_t; +#endif + +// demand loaded sequence groups +typedef struct +{ + char label[32]; // textual name + char name[64]; // file name + cache_user_t cache; // cache index pointer + int data; // hack for group 0 +} mstudioseqgroup_t; + +// sequence descriptions +typedef struct +{ + char label[32]; // sequence label + + float fps; // frames per second + int flags; // looping/non-looping flags + + int activity; + int actweight; + + int numevents; + int eventindex; + + int numframes; // number of frames per sequence + + int numpivots; // number of foot pivots + int pivotindex; + + int motiontype; + int motionbone; + vec3_t linearmovement; + int automoveposindex; + int automoveangleindex; + + vec3_t bbmin; // per sequence bounding box + vec3_t bbmax; + + int numblends; + int animindex; // mstudioanim_t pointer relative to start of sequence group data + // [blend][bone][X, Y, Z, XR, YR, ZR] + + int blendtype[2]; // X, Y, Z, XR, YR, ZR + float blendstart[2]; // starting value + float blendend[2]; // ending value + int blendparent; + + int seqgroup; // sequence group for demand loading + + int entrynode; // transition node at entry + int exitnode; // transition node at exit + int nodeflags; // transition rules + + int nextseq; // auto advancing sequences +} mstudioseqdesc_t; + +// events +#include "studio_event.h" +/* +typedef struct +{ + int frame; + int event; + int type; + char options[64]; +} mstudioevent_t; +*/ + +// pivots +typedef struct +{ + vec3_t org; // pivot point + int start; + int end; +} mstudiopivot_t; + +// attachment +typedef struct +{ + char name[32]; + int type; + int bone; + vec3_t org; // attachment point + vec3_t vectors[3]; +} mstudioattachment_t; + +typedef struct +{ + unsigned short offset[6]; +} mstudioanim_t; + +// animation frames +typedef union +{ + struct { + byte valid; + byte total; + } num; + short value; +} mstudioanimvalue_t; + + + +// body part index +typedef struct +{ + char name[64]; + int nummodels; + int base; + int modelindex; // index into models array +} mstudiobodyparts_t; + + + +// skin info +typedef struct +{ + char name[64]; + int flags; + int width; + int height; + int index; +} mstudiotexture_t; + + +// skin families +// short index[skinfamilies][skinref] + +// studio models +typedef struct +{ + char name[64]; + + int type; + + float boundingradius; + + int nummesh; + int meshindex; + + int numverts; // number of unique vertices + int vertinfoindex; // vertex bone info + int vertindex; // vertex vec3_t + int numnorms; // number of unique surface normals + int norminfoindex; // normal bone info + int normindex; // normal vec3_t + + int numgroups; // deformation groups + int groupindex; +} mstudiomodel_t; + + +// vec3_t boundingbox[model][bone][2]; // complex intersection info + + +// meshes +typedef struct +{ + int numtris; + int triindex; + int skinref; + int numnorms; // per mesh normals + int normindex; // normal vec3_t +} mstudiomesh_t; + +// triangles +#if 0 +typedef struct +{ + short vertindex; // index into vertex array + short normindex; // index into normal array + short s,t; // s,t position on skin +} mstudiotrivert_t; +#endif + +// lighting options +#define STUDIO_NF_FLATSHADE 0x0001 +#define STUDIO_NF_CHROME 0x0002 +#define STUDIO_NF_FULLBRIGHT 0x0004 + +// motion flags +#define STUDIO_X 0x0001 +#define STUDIO_Y 0x0002 +#define STUDIO_Z 0x0004 +#define STUDIO_XR 0x0008 +#define STUDIO_YR 0x0010 +#define STUDIO_ZR 0x0020 +#define STUDIO_LX 0x0040 +#define STUDIO_LY 0x0080 +#define STUDIO_LZ 0x0100 +#define STUDIO_AX 0x0200 +#define STUDIO_AY 0x0400 +#define STUDIO_AZ 0x0800 +#define STUDIO_AXR 0x1000 +#define STUDIO_AYR 0x2000 +#define STUDIO_AZR 0x4000 +#define STUDIO_TYPES 0x7FFF +#define STUDIO_RLOOP 0x8000 // controller that wraps shortest distance + +// sequence flags +#define STUDIO_LOOPING 0x0001 + +// bone flags +#define STUDIO_HAS_NORMALS 0x0001 +#define STUDIO_HAS_VERTICES 0x0002 +#define STUDIO_HAS_BBOX 0x0004 +#define STUDIO_HAS_CHROME 0x0008 // if any of the textures have chrome on them + +#define RAD_TO_STUDIO (32768.0/M_PI) +#define STUDIO_TO_RAD (M_PI/32768.0) + +#endif diff --git a/sdk/hlsdk/pm_shared/pm_debug.h b/sdk/hlsdk/pm_shared/pm_debug.h new file mode 100644 index 0000000..a506d37 --- /dev/null +++ b/sdk/hlsdk/pm_shared/pm_debug.h @@ -0,0 +1,28 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#ifndef PM_DEBUG_H +#define PM_DEBUG_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +void PM_ViewEntity( void ); +void PM_DrawBBox(vec3_t mins, vec3_t maxs, vec3_t origin, int pcolor, float life); +void PM_ParticleLine(vec3_t start, vec3_t end, int pcolor, float life, float vert); +void PM_ShowClipBox( void ); + +#endif // PMOVEDBG_H diff --git a/sdk/hlsdk/pm_shared/pm_defs.h b/sdk/hlsdk/pm_shared/pm_defs.h new file mode 100644 index 0000000..dba6d4e --- /dev/null +++ b/sdk/hlsdk/pm_shared/pm_defs.h @@ -0,0 +1,226 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// pm_defs.h +#if !defined( PM_DEFSH ) +#define PM_DEFSH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +#define MAX_PHYSENTS 600 // Must have room for all entities in the world. +#define MAX_MOVEENTS 64 +#define MAX_CLIP_PLANES 5 + +#define PM_NORMAL 0x00000000 +#define PM_STUDIO_IGNORE 0x00000001 // Skip studio models +#define PM_STUDIO_BOX 0x00000002 // Use boxes for non-complex studio models (even in traceline) +#define PM_GLASS_IGNORE 0x00000004 // Ignore entities with non-normal rendermode +#define PM_WORLD_ONLY 0x00000008 // Only trace against the world + +// Values for flags parameter of PM_TraceLine +#define PM_TRACELINE_PHYSENTSONLY 0 +#define PM_TRACELINE_ANYVISIBLE 1 + + +#include "pm_info.h" + +// PM_PlayerTrace results. +#include "pmtrace.h" + +#if !defined ( USERCMD_H ) +#include "usercmd.h" +#endif + +// physent_t +typedef struct physent_s +{ + char name[32]; // Name of model, or "player" or "world". + int player; + vec3_t origin; // Model's origin in world coordinates. + struct model_s *model; // only for bsp models + struct model_s *studiomodel; // SOLID_BBOX, but studio clip intersections. + vec3_t mins, maxs; // only for non-bsp models + int info; // For client or server to use to identify (index into edicts or cl_entities) + vec3_t angles; // rotated entities need this info for hull testing to work. + + int solid; // Triggers and func_door type WATER brushes are SOLID_NOT + int skin; // BSP Contents for such things like fun_door water brushes. + int rendermode; // So we can ignore glass + + // Complex collision detection. + float frame; + int sequence; + byte controller[4]; + byte blending[2]; + + int movetype; + int takedamage; + int blooddecal; + int team; + int classnumber; + + // For mods + int iuser1; + int iuser2; + int iuser3; + int iuser4; + float fuser1; + float fuser2; + float fuser3; + float fuser4; + vec3_t vuser1; + vec3_t vuser2; + vec3_t vuser3; + vec3_t vuser4; +} physent_t; + + +typedef struct playermove_s +{ + int player_index; // So we don't try to run the PM_CheckStuck nudging too quickly. + qboolean server; // For debugging, are we running physics code on server side? + + qboolean multiplayer; // 1 == multiplayer server + float time; // realtime on host, for reckoning duck timing + float frametime; // Duration of this frame + + vec3_t forward, right, up; // Vectors for angles + // player state + vec3_t origin; // Movement origin. + vec3_t angles; // Movement view angles. + vec3_t oldangles; // Angles before movement view angles were looked at. + vec3_t velocity; // Current movement direction. + vec3_t movedir; // For waterjumping, a forced forward velocity so we can fly over lip of ledge. + vec3_t basevelocity; // Velocity of the conveyor we are standing, e.g. + + // For ducking/dead + vec3_t view_ofs; // Our eye position. + float flDuckTime; // Time we started duck + qboolean bInDuck; // In process of ducking or ducked already? + + // For walking/falling + int flTimeStepSound; // Next time we can play a step sound + int iStepLeft; + + float flFallVelocity; + vec3_t punchangle; + + float flSwimTime; + + float flNextPrimaryAttack; + + int effects; // MUZZLE FLASH, e.g. + + int flags; // FL_ONGROUND, FL_DUCKING, etc. + int usehull; // 0 = regular player hull, 1 = ducked player hull, 2 = point hull + float gravity; // Our current gravity and friction. + float friction; + int oldbuttons; // Buttons last usercmd + float waterjumptime; // Amount of time left in jumping out of water cycle. + qboolean dead; // Are we a dead player? + int deadflag; + int spectator; // Should we use spectator physics model? + int movetype; // Our movement type, NOCLIP, WALK, FLY + + int onground; + int waterlevel; + int watertype; + int oldwaterlevel; + + char sztexturename[256]; + char chtexturetype; + + float maxspeed; + float clientmaxspeed; // Player specific maxspeed + + // For mods + int iuser1; + int iuser2; + int iuser3; + int iuser4; + float fuser1; + float fuser2; + float fuser3; + float fuser4; + vec3_t vuser1; + vec3_t vuser2; + vec3_t vuser3; + vec3_t vuser4; + // world state + // Number of entities to clip against. + int numphysent; + physent_t physents[MAX_PHYSENTS]; + // Number of momvement entities (ladders) + int nummoveent; + // just a list of ladders + physent_t moveents[MAX_MOVEENTS]; + + // All things being rendered, for tracing against things you don't actually collide with + int numvisent; + physent_t visents[ MAX_PHYSENTS ]; + + // input to run through physics. + usercmd_t cmd; + + // Trace results for objects we collided with. + int numtouch; + pmtrace_t touchindex[MAX_PHYSENTS]; + + char physinfo[ MAX_PHYSINFO_STRING ]; // Physics info string + + struct movevars_s *movevars; + vec3_t player_mins[ 4 ]; + vec3_t player_maxs[ 4 ]; + + // Common functions + const char *(*PM_Info_ValueForKey) ( const char *s, const char *key ); + void (*PM_Particle)( float *origin, int color, float life, int zpos, int zvel); + int (*PM_TestPlayerPosition) (float *pos, pmtrace_t *ptrace ); + void (*Con_NPrintf)( int idx, char *fmt, ... ); + void (*Con_DPrintf)( char *fmt, ... ); + void (*Con_Printf)( char *fmt, ... ); + double (*Sys_FloatTime)( void ); + void (*PM_StuckTouch)( int hitent, pmtrace_t *ptraceresult ); + int (*PM_PointContents) (float *p, int *truecontents /*filled in if this is non-null*/ ); + int (*PM_TruePointContents) (float *p); + int (*PM_HullPointContents) ( struct hull_s *hull, int num, float *p); + pmtrace_t (*PM_PlayerTrace) (float *start, float *end, int traceFlags, int ignore_pe ); + struct pmtrace_s *(*PM_TraceLine)( float *start, float *end, int flags, int usehulll, int ignore_pe ); + long (*RandomLong)( long lLow, long lHigh ); + float (*RandomFloat)( float flLow, float flHigh ); + int (*PM_GetModelType)( struct model_s *mod ); + void (*PM_GetModelBounds)( struct model_s *mod, float *mins, float *maxs ); + void *(*PM_HullForBsp)( physent_t *pe, float *offset ); + float (*PM_TraceModel)( physent_t *pEnt, float *start, float *end, trace_t *trace ); + int (*COM_FileSize)(char *filename); + byte *(*COM_LoadFile) (char *path, int usehunk, int *pLength); + void (*COM_FreeFile) ( void *buffer ); + char *(*memfgets)( byte *pMemFile, int fileSize, int *pFilePos, char *pBuffer, int bufferSize ); + + // Functions + // Run functions for this frame? + qboolean runfuncs; + void (*PM_PlaySound) ( int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch ); + const char *(*PM_TraceTexture) ( int ground, float *vstart, float *vend ); + void (*PM_PlaybackEventFull) ( int flags, int clientindex, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); + + pmtrace_t (*PM_PlayerTraceEx) (float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ) ); + int (*PM_TestPlayerPositionEx) (float *pos, pmtrace_t *ptrace, int (*pfnIgnore)( physent_t *pe ) ); + struct pmtrace_s *(*PM_TraceLineEx)( float *start, float *end, int flags, int usehulll, int (*pfnIgnore)( physent_t *pe ) ); +} playermove_t; + +#endif diff --git a/sdk/hlsdk/pm_shared/pm_info.h b/sdk/hlsdk/pm_shared/pm_info.h new file mode 100644 index 0000000..fa3cc19 --- /dev/null +++ b/sdk/hlsdk/pm_shared/pm_info.h @@ -0,0 +1,26 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +// Physics info string definition +#if !defined( PM_INFOH ) +#define PM_INFOH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +#define MAX_PHYSINFO_STRING 256 + +#endif // PM_INFOH diff --git a/sdk/hlsdk/pm_shared/pm_materials.h b/sdk/hlsdk/pm_shared/pm_materials.h new file mode 100644 index 0000000..4140781 --- /dev/null +++ b/sdk/hlsdk/pm_shared/pm_materials.h @@ -0,0 +1,37 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +#if !defined( PM_MATERIALSH ) +#define PM_MATERIALSH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +#define CBTEXTURENAMEMAX 13 // only load first n chars of name + +#define CHAR_TEX_CONCRETE 'C' // texture types +#define CHAR_TEX_METAL 'M' +#define CHAR_TEX_DIRT 'D' +#define CHAR_TEX_VENT 'V' +#define CHAR_TEX_GRATE 'G' +#define CHAR_TEX_TILE 'T' +#define CHAR_TEX_SLOSH 'S' +#define CHAR_TEX_WOOD 'W' +#define CHAR_TEX_COMPUTER 'P' +#define CHAR_TEX_GLASS 'Y' +#define CHAR_TEX_FLESH 'F' + +#endif // !PM_MATERIALSH diff --git a/sdk/hlsdk/pm_shared/pm_movevars.h b/sdk/hlsdk/pm_shared/pm_movevars.h new file mode 100644 index 0000000..66c99ee --- /dev/null +++ b/sdk/hlsdk/pm_shared/pm_movevars.h @@ -0,0 +1,47 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +// pm_movevars.h +#if !defined( PM_MOVEVARSH ) +#define PM_MOVEVARSH + +// movevars_t // Physics variables. +typedef struct movevars_s movevars_t; + +struct movevars_s +{ + float gravity; // Gravity for map + float stopspeed; // Deceleration when not moving + float maxspeed; // Max allowed speed + float spectatormaxspeed; + float accelerate; // Acceleration factor + float airaccelerate; // Same for when in open air + float wateraccelerate; // Same for when in water + float friction; + float edgefriction; // Extra friction near dropofs + float waterfriction; // Less in water + float entgravity; // 1.0 + float bounce; // Wall bounce value. 1.0 + float stepsize; // sv_stepsize; + float maxvelocity; // maximum server velocity. + float zmax; // Max z-buffer range (for GL) + float waveHeight; // Water wave height (for GL) + qboolean footsteps; // Play footstep sounds + char skyName[32]; // Name of the sky map + float rollangle; + float rollspeed; + float skycolor_r; // Sky color + float skycolor_g; // + float skycolor_b; // + float skyvec_x; // Sky vector + float skyvec_y; // + float skyvec_z; // +}; + +extern movevars_t movevars; + +#endif diff --git a/sdk/hlsdk/pm_shared/pm_shared.h b/sdk/hlsdk/pm_shared/pm_shared.h new file mode 100644 index 0000000..153c539 --- /dev/null +++ b/sdk/hlsdk/pm_shared/pm_shared.h @@ -0,0 +1,40 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +// +// pm_shared.h +// +#if !defined( PM_SHAREDH ) +#define PM_SHAREDH +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + +void PM_Init( struct playermove_s *ppmove ); +void PM_Move ( struct playermove_s *ppmove, int server ); +char PM_FindTextureType( char *name ); + +// Spectator Movement modes (stored in pev->iuser1, so the physics code can get at them) +#define OBS_NONE 0 +#define OBS_CHASE_LOCKED 1 +#define OBS_CHASE_FREE 2 +#define OBS_ROAMING 3 +#define OBS_IN_EYE 4 +#define OBS_MAP_FREE 5 +#define OBS_MAP_CHASE 6 + +#endif diff --git a/sdk/metamod/api_info.h b/sdk/metamod/api_info.h new file mode 100644 index 0000000..86711fd --- /dev/null +++ b/sdk/metamod/api_info.h @@ -0,0 +1,296 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// api_info.h - structures to store info about api routines + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef API_INFO_H +#define API_INFO_H + +#include "types_meta.h" // mBOOL + + +#define P_PRE 0 // plugin function called before gamedll +#define P_POST 1 // plugin function called after gamedll + + +typedef struct api_info_s { + mBOOL trace; // if true, log info about this function + int loglevel; // level at which to log info about this function + char *name; // string representation of function name +} api_info_t; + + +// DLL api functions +typedef struct dllapi_info_s { + api_info_t pfnGameInit; + api_info_t pfnSpawn; + api_info_t pfnThink; + api_info_t pfnUse; + api_info_t pfnTouch; + api_info_t pfnBlocked; + api_info_t pfnKeyValue; + api_info_t pfnSave; + api_info_t pfnRestore; + api_info_t pfnSetAbsBox; + api_info_t pfnSaveWriteFields; + api_info_t pfnSaveReadFields; + api_info_t pfnSaveGlobalState; + api_info_t pfnRestoreGlobalState; + api_info_t pfnResetGlobalState; + api_info_t pfnClientConnect; + api_info_t pfnClientDisconnect; + api_info_t pfnClientKill; + api_info_t pfnClientPutInServer; + api_info_t pfnClientCommand; + api_info_t pfnClientUserInfoChanged; + api_info_t pfnServerActivate; + api_info_t pfnServerDeactivate; + api_info_t pfnPlayerPreThink; + api_info_t pfnPlayerPostThink; + api_info_t pfnStartFrame; + api_info_t pfnParmsNewLevel; + api_info_t pfnParmsChangeLevel; + api_info_t pfnGetGameDescription; + api_info_t pfnPlayerCustomization; + api_info_t pfnSpectatorConnect; + api_info_t pfnSpectatorDisconnect; + api_info_t pfnSpectatorThink; + api_info_t pfnSys_Error; + api_info_t pfnPM_Move; + api_info_t pfnPM_Init; + api_info_t pfnPM_FindTextureType; + api_info_t pfnSetupVisibility; + api_info_t pfnUpdateClientData; + api_info_t pfnAddToFullPack; + api_info_t pfnCreateBaseline; + api_info_t pfnRegisterEncoders; + api_info_t pfnGetWeaponData; + api_info_t pfnCmdStart; + api_info_t pfnCmdEnd; + api_info_t pfnConnectionlessPacket; + api_info_t pfnGetHullBounds; + api_info_t pfnCreateInstancedBaselines; + api_info_t pfnInconsistentFile; + api_info_t pfnAllowLagCompensation; + api_info_t END; +} dllapi_info_t; + + +// "New" api functions +typedef struct newapi_info_s { + api_info_t pfnOnFreeEntPrivateData; + api_info_t pfnGameShutdown; + api_info_t pfnShouldCollide; + // Added 2005/08/11 (no SDK update) + api_info_t pfnCvarValue; + // Added 2005/11/22 (no SDK update) + api_info_t pfnCvarValue2; + api_info_t END; +} newapi_info_t; + + +// Engine functions +typedef struct engine_info_s { + api_info_t pfnPrecacheModel; + api_info_t pfnPrecacheSound; + api_info_t pfnSetModel; + api_info_t pfnModelIndex; + api_info_t pfnModelFrames; + api_info_t pfnSetSize; + api_info_t pfnChangeLevel; + api_info_t pfnGetSpawnParms; + api_info_t pfnSaveSpawnParms; + api_info_t pfnVecToYaw; + api_info_t pfnVecToAngles; + api_info_t pfnMoveToOrigin; + api_info_t pfnChangeYaw; + api_info_t pfnChangePitch; + api_info_t pfnFindEntityByString; + api_info_t pfnGetEntityIllum; + api_info_t pfnFindEntityInSphere; + api_info_t pfnFindClientInPVS; + api_info_t pfnEntitiesInPVS; + api_info_t pfnMakeVectors; + api_info_t pfnAngleVectors; + api_info_t pfnCreateEntity; + api_info_t pfnRemoveEntity; + api_info_t pfnCreateNamedEntity; + api_info_t pfnMakeStatic; + api_info_t pfnEntIsOnFloor; + api_info_t pfnDropToFloor; + api_info_t pfnWalkMove; + api_info_t pfnSetOrigin; + api_info_t pfnEmitSound; + api_info_t pfnEmitAmbientSound; + api_info_t pfnTraceLine; + api_info_t pfnTraceToss; + api_info_t pfnTraceMonsterHull; + api_info_t pfnTraceHull; + api_info_t pfnTraceModel; + api_info_t pfnTraceTexture; + api_info_t pfnTraceSphere; + api_info_t pfnGetAimVector; + api_info_t pfnServerCommand; + api_info_t pfnServerExecute; + api_info_t pfnClientCommand; + api_info_t pfnParticleEffect; + api_info_t pfnLightStyle; + api_info_t pfnDecalIndex; + api_info_t pfnPointContents; + api_info_t pfnMessageBegin; + api_info_t pfnMessageEnd; + api_info_t pfnWriteByte; + api_info_t pfnWriteChar; + api_info_t pfnWriteShort; + api_info_t pfnWriteLong; + api_info_t pfnWriteAngle; + api_info_t pfnWriteCoord; + api_info_t pfnWriteString; + api_info_t pfnWriteEntity; + api_info_t pfnCVarRegister; + api_info_t pfnCVarGetFloat; + api_info_t pfnCVarGetString; + api_info_t pfnCVarSetFloat; + api_info_t pfnCVarSetString; + api_info_t pfnAlertMessage; + api_info_t pfnEngineFprintf; + api_info_t pfnPvAllocEntPrivateData; + api_info_t pfnPvEntPrivateData; + api_info_t pfnFreeEntPrivateData; + api_info_t pfnSzFromIndex; + api_info_t pfnAllocString; + api_info_t pfnGetVarsOfEnt; + api_info_t pfnPEntityOfEntOffset; + api_info_t pfnEntOffsetOfPEntity; + api_info_t pfnIndexOfEdict; + api_info_t pfnPEntityOfEntIndex; + api_info_t pfnFindEntityByVars; + api_info_t pfnGetModelPtr; + api_info_t pfnRegUserMsg; + api_info_t pfnAnimationAutomove; + api_info_t pfnGetBonePosition; + api_info_t pfnFunctionFromName; + api_info_t pfnNameForFunction; + api_info_t pfnClientPrintf; + api_info_t pfnServerPrint; + api_info_t pfnCmd_Args; + api_info_t pfnCmd_Argv; + api_info_t pfnCmd_Argc; + api_info_t pfnGetAttachment; + api_info_t pfnCRC32_Init; + api_info_t pfnCRC32_ProcessBuffer; + api_info_t pfnCRC32_ProcessByte; + api_info_t pfnCRC32_Final; + api_info_t pfnRandomLong; + api_info_t pfnRandomFloat; + api_info_t pfnSetView; + api_info_t pfnTime; + api_info_t pfnCrosshairAngle; + api_info_t pfnLoadFileForMe; + api_info_t pfnFreeFile; + api_info_t pfnEndSection; + api_info_t pfnCompareFileTime; + api_info_t pfnGetGameDir; + api_info_t pfnCvar_RegisterVariable; + api_info_t pfnFadeClientVolume; + api_info_t pfnSetClientMaxspeed; + api_info_t pfnCreateFakeClient; + api_info_t pfnRunPlayerMove; + api_info_t pfnNumberOfEntities; + api_info_t pfnGetInfoKeyBuffer; + api_info_t pfnInfoKeyValue; + api_info_t pfnSetKeyValue; + api_info_t pfnSetClientKeyValue; + api_info_t pfnIsMapValid; + api_info_t pfnStaticDecal; + api_info_t pfnPrecacheGeneric; + api_info_t pfnGetPlayerUserId; + api_info_t pfnBuildSoundMsg; + api_info_t pfnIsDedicatedServer; + api_info_t pfnCVarGetPointer; + api_info_t pfnGetPlayerWONId; + api_info_t pfnInfo_RemoveKey; + api_info_t pfnGetPhysicsKeyValue; + api_info_t pfnSetPhysicsKeyValue; + api_info_t pfnGetPhysicsInfoString; + api_info_t pfnPrecacheEvent; + api_info_t pfnPlaybackEvent; + api_info_t pfnSetFatPVS; + api_info_t pfnSetFatPAS; + api_info_t pfnCheckVisibility; + api_info_t pfnDeltaSetField; + api_info_t pfnDeltaUnsetField; + api_info_t pfnDeltaAddEncoder; + api_info_t pfnGetCurrentPlayer; + api_info_t pfnCanSkipPlayer; + api_info_t pfnDeltaFindField; + api_info_t pfnDeltaSetFieldByIndex; + api_info_t pfnDeltaUnsetFieldByIndex; + api_info_t pfnSetGroupMask; + api_info_t pfnCreateInstancedBaseline; + api_info_t pfnCvar_DirectSet; + api_info_t pfnForceUnmodified; + api_info_t pfnGetPlayerStats; + api_info_t pfnAddServerCommand; + // Added in SDK 2.2: + api_info_t pfnVoice_GetClientListening; + api_info_t pfnVoice_SetClientListening; + // Added for HL 1109 (no SDK update): + api_info_t pfnGetPlayerAuthId; + // Added 2003/11/10 (no SDK update): + api_info_t pfnSequenceGet; + api_info_t pfnSequencePickSentence; + api_info_t pfnGetFileSize; + api_info_t pfnGetApproxWavePlayLen; + api_info_t pfnIsCareerMatch; + api_info_t pfnGetLocalizedStringLength; + api_info_t pfnRegisterTutorMessageShown; + api_info_t pfnGetTimesTutorMessageShown; + api_info_t pfnProcessTutorMessageDecayBuffer; + api_info_t pfnConstructTutorMessageDecayBuffer; + api_info_t pfnResetTutorMessageDecayData; + // Added 2005/08/11 (no SDK update) + api_info_t pfnQueryClientCvarValue; + // Added 2005/11/22 (no SDK update) + api_info_t pfnQueryClientCvarValue2; + // end + api_info_t END; +} engine_info_t; + + +extern dllapi_info_t dllapi_info; +extern newapi_info_t newapi_info; +extern engine_info_t engine_info; + +#endif /* API_INFO_H */ diff --git a/sdk/metamod/commands_meta.h b/sdk/metamod/commands_meta.h new file mode 100644 index 0000000..69aa0e9 --- /dev/null +++ b/sdk/metamod/commands_meta.h @@ -0,0 +1,81 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// commands_meta.h - prototypes for console commands + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef COMMANDS_META_H +#define COMMANDS_META_H + +#include "types_meta.h" // mBOOL + +// Flags to use for meta_cmd_doplug(), to operate on existing plugins; note +// "load" operates on a non-existing plugin thus isn't included here. +typedef enum { + PC_NULL = 0, + PC_PAUSE, // pause the plugin + PC_UNPAUSE, // unpause the plugin + PC_UNLOAD, // unload the plugin + PC_RELOAD, // unload the plugin and load it again + PC_RETRY, // retry a failed operation (usually load/attach) + PC_INFO, // show all info about the plugin + PC_CLEAR, // remove a failed plugin from the list + PC_FORCE_UNLOAD, // forcibly unload the plugin + PC_REQUIRE, // require that this plugin is loaded/running +} PLUG_CMD; + +void meta_register_cmdcvar(); + +void svr_meta(void); + +void cmd_meta_usage(void); +void cmd_meta_version(void); +void cmd_meta_gpl(void); + +void cmd_meta_game(void); +void cmd_meta_refresh(void); +void cmd_meta_load(void); + +void cmd_meta_pluginlist(void); +void cmd_meta_cmdlist(void); +void cmd_meta_cvarlist(void); +void cmd_meta_config(void); + +void cmd_doplug(PLUG_CMD pcmd); + +void client_meta(edict_t *pEntity); +void client_meta_usage(edict_t *pEntity); +void client_meta_version(edict_t *pEntity); +void client_meta_pluginlist(edict_t *pEntity); + +#endif /* COMMANDS_META_H */ diff --git a/sdk/metamod/conf_meta.h b/sdk/metamod/conf_meta.h new file mode 100644 index 0000000..d8dfbbb --- /dev/null +++ b/sdk/metamod/conf_meta.h @@ -0,0 +1,96 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// conf_meta.h - configfile reading + +// Modeled after mutt/init.[ch]. + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef CONF_META_H +#define CONF_META_H + +#include "types_meta.h" // mBOOL + +// Max length of line in config file. +#define MAX_CONF_LEN 1024 + +// Supported config value-types. +typedef enum { + CF_NONE=0, + CF_INT, + CF_BOOL, + CF_STR, + CF_PATH, +#if 0 + CF_CVAR, + CF_CMD, +#endif +} cf_type_t; + +typedef mBOOL (*SETOPT_FN) (char *key, char *value); + +typedef struct option_s { + char *name; // option name + cf_type_t type; // option type + void *dest; // addr of destination variable, or handler function + char *init; // initial value, as a string, just as config file would +} option_t; + +class MConfig { + private: + // data + option_t *list; + char *filename; + // functions + option_t *find(char *lookup); + mBOOL set(option_t *setp, char *value); + // Private; to satisfy -Weffc++ "has pointer data members but does + // not override" copy/assignment constructor. + void operator=(const MConfig &src); + MConfig(const MConfig &src); + public: + // contructor + MConfig(void); + // data + int debuglevel; // to use for meta_debug + char *gamedll; // string if specified in config.ini + char *plugins_file; // ie metamod.ini, plugins.ini + char *exec_cfg; // ie metaexec.cfg, exec.cfg + // functions + void init(option_t *global_options); + mBOOL load(char *filename); + mBOOL set(char *key, char *value); + void show(void); +}; + +#endif /* CONF_META_H */ diff --git a/sdk/metamod/dllapi.h b/sdk/metamod/dllapi.h new file mode 100644 index 0000000..01e7f95 --- /dev/null +++ b/sdk/metamod/dllapi.h @@ -0,0 +1,192 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// dllapi.h - prototypes and typedefs for Half-Life DLL API routines + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef DLLAPI_H +#define DLLAPI_H + +#include "sdk_util.h" // BOOL +#include "osdep.h" // DLLEXPORT, etc + +// Typedefs for these are provided in SDK engine/eiface.h, but I didn't +// like the names (APIFUNCTION, APIFUNCTION2, NEW_DLL_FUNCTIONS_FN). +typedef int (*GETENTITYAPI_FN) (DLL_FUNCTIONS *pFunctionTable, int interfaceVersion); +typedef int (*GETENTITYAPI2_FN) (DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion); +typedef int (*GETNEWDLLFUNCTIONS_FN) (NEW_DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion); + +// From SDK dlls/cbase.h: +C_DLLEXPORT int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ); +C_DLLEXPORT int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ); + +// No example in SDK.. +// From Adminmod dll.cpp: +C_DLLEXPORT int GetNewDLLFunctions( NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion ); + + +// From SDK dlls/game.h: +extern void mm_GameDLLInit( void ); + +// From SDK dlls/cbase.h: +extern int mm_DispatchSpawn( edict_t *pent ); +extern void mm_DispatchThink( edict_t *pent ); +extern void mm_DispatchUse( edict_t *pentUsed, edict_t *pentOther ); +extern void mm_DispatchTouch( edict_t *pentTouched, edict_t *pentOther ); +extern void mm_DispatchBlocked( edict_t *pentBlocked, edict_t *pentOther ); +extern void mm_DispatchKeyValue( edict_t *pentKeyvalue, KeyValueData *pkvd ); +extern void mm_DispatchSave( edict_t *pent, SAVERESTOREDATA *pSaveData ); +extern int mm_DispatchRestore( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity ); +extern void mm_DispatchObjectCollisionBox( edict_t *pent ); +extern void mm_SaveWriteFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); +extern void mm_SaveReadFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); +extern void mm_SaveGlobalState( SAVERESTOREDATA *pSaveData ); +extern void mm_RestoreGlobalState( SAVERESTOREDATA *pSaveData ); +extern void mm_ResetGlobalState( void ); + +// From SDK dlls/client.h: +extern BOOL mm_ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); +extern void mm_ClientDisconnect( edict_t *pEntity ); +extern void mm_ClientKill( edict_t *pEntity ); +extern void mm_ClientPutInServer( edict_t *pEntity ); +extern void mm_ClientCommand( edict_t *pEntity ); +extern void mm_ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ); +extern void mm_ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ); +extern void mm_ServerDeactivate( void ); +extern void mm_PlayerPreThink( edict_t *pEntity ); +extern void mm_PlayerPostThink( edict_t *pEntity ); +extern void mm_StartFrame( void ); +extern void mm_ParmsNewLevel( void ); +extern void mm_ParmsChangeLevel( void ); +extern const char *mm_GetGameDescription( void ); +extern void mm_PlayerCustomization( edict_t *pEntity, customization_t *pCust ); +extern void mm_SpectatorConnect ( edict_t *pEntity ); +extern void mm_SpectatorDisconnect ( edict_t *pEntity ); +extern void mm_SpectatorThink ( edict_t *pEntity ); +extern void mm_Sys_Error( const char *error_string ); + +// From SDK pm_shared/pm_shared.h: +extern void mm_PM_Move ( struct playermove_s *ppmove, int server ); +extern void mm_PM_Init ( struct playermove_s *ppmove ); +extern char mm_PM_FindTextureType ( char *name ); + +// From SDK dlls/client.h: +extern void mm_SetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas ); +extern void mm_UpdateClientData ( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd ); +extern int mm_AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet ); +extern void mm_CreateBaseline( int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs ); +extern void mm_RegisterEncoders( void ); +extern int mm_GetWeaponData( struct edict_s *player, struct weapon_data_s *info ); +extern void mm_CmdStart( const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed ); +extern void mm_CmdEnd ( const edict_t *player ); +extern int mm_ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); +extern int mm_GetHullBounds( int hullnumber, float *mins, float *maxs ); +extern void mm_CreateInstancedBaselines ( void ); +extern int mm_InconsistentFile( const edict_t *player, const char *filename, char *disconnect_message ); +extern int mm_AllowLagCompensation( void ); + +// No example from SDK... +extern void mm_OnFreeEntPrivateData(edict_t pEnt); +extern void mm_GameShutdown(void); +extern int mm_ShouldCollide(edict_t *pentTouched, edict_t *pentOther); +//Added 2005-08-11 (no SDK update) +extern void mm_CvarValue(const edict_t *pEnt, const char *value); //! Obsolete! Use mm_CvarValue2 instead +//Added 2005-11-22 (no SDK update) +extern void mm_CvarValue2(const edict_t *pEnt, int requestID, const char *cvarName, const char *value); + + +// Typedefs for the above functions: + +typedef void (*FN_GAMEINIT) ( void ); +typedef int (*FN_DISPATCHSPAWN) ( edict_t *pent ); +typedef void (*FN_DISPATCHTHINK) ( edict_t *pent ); +typedef void (*FN_DISPATCHUSE) ( edict_t *pentUsed, edict_t *pentOther ); +typedef void (*FN_DISPATCHTOUCH) ( edict_t *pentTouched, edict_t *pentOther ); +typedef void (*FN_DISPATCHBLOCKED) ( edict_t *pentBlocked, edict_t *pentOther ); +typedef void (*FN_DISPATCHKEYVALUE) ( edict_t *pentKeyvalue, KeyValueData *pkvd ); +typedef void (*FN_DISPATCHSAVE) ( edict_t *pent, SAVERESTOREDATA *pSaveData ); +typedef int (*FN_DISPATCHRESTORE) ( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity ); +typedef void (*FN_DISPATCHOBJECTCOLLISIONBOX) ( edict_t *pent ); +typedef void (*FN_SAVEWRITEFIELDS) ( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); +typedef void (*FN_SAVEREADFIELDS) ( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); +typedef void (*FN_SAVEGLOBALSTATE) ( SAVERESTOREDATA *pSaveData ); +typedef void (*FN_RESTOREGLOBALSTATE) ( SAVERESTOREDATA *pSaveData ); +typedef void (*FN_RESETGLOBALSTATE) ( void ); + +typedef BOOL (*FN_CLIENTCONNECT) ( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); +typedef void (*FN_CLIENTDISCONNECT) ( edict_t *pEntity ); +typedef void (*FN_CLIENTKILL) ( edict_t *pEntity ); +typedef void (*FN_CLIENTPUTINSERVER) ( edict_t *pEntity ); +typedef void (*FN_CLIENTCOMMAND) ( edict_t *pEntity ); +typedef void (*FN_CLIENTUSERINFOCHANGED) ( edict_t *pEntity, char *infobuffer ); +typedef void (*FN_SERVERACTIVATE) ( edict_t *pEdictList, int edictCount, int clientMax ); +typedef void (*FN_SERVERDEACTIVATE) ( void ); +typedef void (*FN_PLAYERPRETHINK) ( edict_t *pEntity ); +typedef void (*FN_PLAYERPOSTTHINK) ( edict_t *pEntity ); +typedef void (*FN_STARTFRAME) ( void ); +typedef void (*FN_PARMSNEWLEVEL) ( void ); +typedef void (*FN_PARMSCHANGELEVEL) ( void ); +typedef const char *(*FN_GETGAMEDESCRIPTION) ( void ); +typedef void (*FN_PLAYERCUSTOMIZATION) ( edict_t *pEntity, customization_t *pCust ); +typedef void (*FN_SPECTATORCONNECT) ( edict_t *pEntity ); +typedef void (*FN_SPECTATORDISCONNECT) ( edict_t *pEntity ); +typedef void (*FN_SPECTATORTHINK) ( edict_t *pEntity ); +typedef void (*FN_SYS_ERROR) ( const char *error_string ); + +typedef void (*FN_PM_MOVE) ( struct playermove_s *ppmove, int server ); +typedef void (*FN_PM_INIT) ( struct playermove_s *ppmove ); +typedef char (*FN_PM_FINDTEXTURETYPE) ( char *name ); + +typedef void (*FN_SETUPVISIBILITY) ( edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas ); +typedef void (*FN_UPDATECLIENTDATA) ( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd ); +typedef int (*FN_ADDTOFULLPACK) ( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet ); +typedef void (*FN_CREATEBASELINE) ( int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs ); +typedef void (*FN_REGISTERENCODERS) ( void ); +typedef int (*FN_GETWEAPONDATA) ( struct edict_s *player, struct weapon_data_s *info ); +typedef void (*FN_CMDSTART) ( const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed ); +typedef void (*FN_CMDEND) ( const edict_t *player ); +typedef int (*FN_CONNECTIONLESSPACKET) ( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); +typedef int (*FN_GETHULLBOUNDS) ( int hullnumber, float *mins, float *maxs ); +typedef void (*FN_CREATEINSTANCEDBASELINES) ( void ); +typedef int (*FN_INCONSISTENTFILE) ( const edict_t *player, const char *filename, char *disconnect_message ); +typedef int (*FN_ALLOWLAGCOMPENSATION) ( void ); + +typedef void (*FN_ONFREEENTPRIVATEDATA) (edict_t *pEnt); +typedef void (*FN_GAMESHUTDOWN) (void); +typedef int (*FN_SHOULDCOLLIDE) (edict_t *pentTouched, edict_t *pentOther); +//Added 2005-08-11 (no SDK update) +typedef void (*FN_CVARVALUE)(const edict_t *pEnt, const char *value); //! Obsolete! Use FN_CVARVALUE2 instead +//Added 2005-11-22 (no SDK update) +typedef void (*FN_CVARVALUE2)(const edict_t *pEnt, int requestID, const char *cvarName, const char *value); + +#endif /* DLLAPI_H */ diff --git a/sdk/metamod/engine_api.h b/sdk/metamod/engine_api.h new file mode 100644 index 0000000..13f2544 --- /dev/null +++ b/sdk/metamod/engine_api.h @@ -0,0 +1,464 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// engine_api.h - prototypes and typedefs for Half-Life engine functions + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef ENGINE_API_H +#define ENGINE_API_H + +#include + +// Plugin's GetEngineFunctions, called by metamod. +typedef int (*GET_ENGINE_FUNCTIONS_FN) (enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion); + +// According to SDK engine/eiface.h: +//! enginefuncs_t +//! ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 138 +#define ENGINE_INTERFACE_VERSION 138 + +// Protect against other projects which use this include file but use the +// normal enginefuncs_t type for their meta_engfuncs. +#ifdef METAMOD_CORE +# include "meta_eiface.h" // meta_enginefuncs_t +extern meta_enginefuncs_t meta_engfuncs; +#else +extern enginefuncs_t meta_engfuncs; +#endif + +// From SDK engine/eiface.h: +extern int mm_PrecacheModel(char *s); +extern int mm_PrecacheSound(char *s); +extern void mm_SetModel(edict_t *e, const char *m); +extern int mm_ModelIndex(const char *m); +extern int mm_ModelFrames(int modelIndex); + +extern void mm_SetSize(edict_t *e, const float *rgflMin, const float *rgflMax); +extern void mm_ChangeLevel(char *s1, char *s2); +extern void mm_GetSpawnParms(edict_t *ent); +extern void mm_SaveSpawnParms(edict_t *ent); + +extern float mm_VecToYaw(const float *rgflVector); +extern void mm_VecToAngles(const float *rgflVectorIn, float *rgflVectorOut); +extern void mm_MoveToOrigin(edict_t *ent, const float *pflGoal, float dist, int iMoveType); +extern void mm_ChangeYaw(edict_t *ent); +extern void mm_ChangePitch(edict_t *ent); + +extern edict_t *mm_FindEntityByString(edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue); +extern int mm_GetEntityIllum(edict_t *pEnt); +extern edict_t *mm_FindEntityInSphere(edict_t *pEdictStartSearchAfter, const float *org, float rad); +extern edict_t *mm_FindClientInPVS(edict_t *pEdict); +extern edict_t *mm_EntitiesInPVS(edict_t *pplayer); + +extern void mm_MakeVectors(const float *rgflVector); +extern void mm_AngleVectors(const float *rgflVector, float *forward, float *right, float *up); + +extern edict_t *mm_CreateEntity(void); +extern void mm_RemoveEntity(edict_t *e); +extern edict_t *mm_CreateNamedEntity(int className); + +extern void mm_MakeStatic(edict_t *ent); +extern int mm_EntIsOnFloor(edict_t *e); +extern int mm_DropToFloor(edict_t *e); + +extern int mm_WalkMove(edict_t *ent, float yaw, float dist, int iMode); +extern void mm_SetOrigin(edict_t *e, const float *rgflOrigin); + +extern void mm_EmitSound(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch); +extern void mm_EmitAmbientSound(edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch); + +extern void mm_TraceLine(const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); +extern void mm_TraceToss(edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr); +extern int mm_TraceMonsterHull(edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); +extern void mm_TraceHull(const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr); +extern void mm_TraceModel(const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr); +extern const char *mm_TraceTexture(edict_t *pTextureEntity, const float *v1, const float *v2 ); +extern void mm_TraceSphere(const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr); +extern void mm_GetAimVector(edict_t *ent, float speed, float *rgflReturn); + +extern void mm_ServerCommand(char *str); +extern void mm_ServerExecute(void); +extern void ClientCommand(edict_t *pEdict, char *szFmt, ...); + +extern void mm_ParticleEffect(const float *org, const float *dir, float color, float count); +extern void mm_LightStyle(int style, char *val); +extern int mm_DecalIndex(const char *name); +extern int mm_PointContents(const float *rgflVector); + +extern void mm_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); +extern void mm_MessageEnd(void); + +extern void mm_WriteByte(int iValue); +extern void mm_WriteChar(int iValue); +extern void mm_WriteShort(int iValue); +extern void mm_WriteLong(int iValue); +extern void mm_WriteAngle(float flValue); +extern void mm_WriteCoord(float flValue); +extern void mm_WriteString(const char *sz); +extern void mm_WriteEntity(int iValue); + +extern void mm_CVarRegister(cvar_t *pCvar); +extern float mm_CVarGetFloat(const char *szVarName); +extern const char* mm_CVarGetString(const char *szVarName); +extern void mm_CVarSetFloat(const char *szVarName, float flValue); +extern void mm_CVarSetString(const char *szVarName, const char *szValue); + +extern void mm_AlertMessage(ALERT_TYPE atype, char *szFmt, ...); +#ifdef HLSDK_3_2_OLD_EIFACE +extern void mm_EngineFprintf(FILE *pfile, char *szFmt, ...); +#else +extern void mm_EngineFprintf(void *pfile, char *szFmt, ...); +#endif + +#ifdef HLSDK_3_2_OLD_EIFACE +extern void *mm_PvAllocEntPrivateData(edict_t *pEdict, long cb); +#else +extern void *mm_PvAllocEntPrivateData(edict_t *pEdict, int32 cb); +#endif +extern void *mm_PvEntPrivateData(edict_t *pEdict); +extern void mm_FreeEntPrivateData(edict_t *pEdict); + +extern const char *mm_SzFromIndex(int iString); +extern int mm_AllocString(const char *szValue); + +extern struct entvars_s *mm_GetVarsOfEnt(edict_t *pEdict); +extern edict_t *mm_PEntityOfEntOffset(int iEntOffset); +extern int mm_EntOffsetOfPEntity(const edict_t *pEdict); +extern int mm_IndexOfEdict(const edict_t *pEdict); +extern edict_t *mm_PEntityOfEntIndex(int iEntIndex); +extern edict_t *mm_FindEntityByVars(struct entvars_s *pvars); +extern void *mm_GetModelPtr(edict_t *pEdict); + +extern int mm_RegUserMsg(const char *pszName, int iSize); + +extern void mm_AnimationAutomove(const edict_t *pEdict, float flTime); +extern void mm_GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles ); + +#ifdef HLSDK_3_2_OLD_EIFACE +extern unsigned long mm_FunctionFromName( const char *pName ); +extern const char *mm_NameForFunction( unsigned long function ); +#else +extern uint32 mm_FunctionFromName( const char *pName ); +extern const char *mm_NameForFunction( uint32 function ); +#endif + +extern void mm_ClientPrintf( edict_t *pEdict, PRINT_TYPE ptype, const char *szMsg ); //! JOHN: engine callbacks so game DLL can print messages to individual clients +extern void mm_ServerPrint( const char *szMsg ); + +extern const char *mm_Cmd_Args( void ); //! these 3 added +extern const char *mm_Cmd_Argv( int argc ); //! so game DLL can easily +extern int mm_Cmd_Argc( void ); //! access client 'cmd' strings + +extern void mm_GetAttachment(const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles ); + +extern void mm_CRC32_Init(CRC32_t *pulCRC); +extern void mm_CRC32_ProcessBuffer(CRC32_t *pulCRC, void *p, int len); +extern void mm_CRC32_ProcessByte(CRC32_t *pulCRC, unsigned char ch); +extern CRC32_t mm_CRC32_Final(CRC32_t pulCRC); + +#ifdef HLSDK_3_2_OLD_EIFACE +extern long mm_RandomLong(long lLow, long lHigh); +#else +extern int32 mm_RandomLong(int32 lLow, int32 lHigh); +#endif +extern float mm_RandomFloat(float flLow, float flHigh); + +extern void mm_SetView(const edict_t *pClient, const edict_t *pViewent ); +extern float mm_Time( void ); +extern void mm_CrosshairAngle(const edict_t *pClient, float pitch, float yaw); + +extern byte * mm_LoadFileForMe(char *filename, int *pLength); +extern void mm_FreeFile(void *buffer); + +extern void mm_EndSection(const char *pszSectionName); //! trigger_endsection +extern int mm_CompareFileTime(char *filename1, char *filename2, int *iCompare); +extern void mm_GetGameDir(char *szGetGameDir); +extern void mm_Cvar_RegisterVariable(cvar_t *variable); +extern void mm_FadeClientVolume(const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds); +extern void mm_SetClientMaxspeed(const edict_t *pEdict, float fNewMaxspeed); +extern edict_t * mm_CreateFakeClient(const char *netname); //! returns NULL if fake client can't be created +extern void mm_RunPlayerMove(edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec ); +extern int mm_NumberOfEntities(void); + +extern char *mm_GetInfoKeyBuffer(edict_t *e); //! passing in NULL gets the serverinfo +extern char *mm_InfoKeyValue(char *infobuffer, char *key); +extern void mm_SetKeyValue(char *infobuffer, char *key, char *value); +extern void mm_SetClientKeyValue(int clientIndex, char *infobuffer, char *key, char *value); + +extern int mm_IsMapValid(char *filename); +extern void mm_StaticDecal( const float *origin, int decalIndex, int entityIndex, int modelIndex ); +extern int mm_PrecacheGeneric(char *s); +extern int mm_GetPlayerUserId(edict_t *e ); //! returns the server assigned userid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients +extern void mm_BuildSoundMsg(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); +extern int mm_IsDedicatedServer(void);//! is this a dedicated server? +extern cvar_t *mm_CVarGetPointer(const char *szVarName); +extern unsigned int mm_GetPlayerWONId(edict_t *e); //! returns the server assigned WONid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients + +//! YWB 8/1/99 TFF Physics additions +extern void mm_Info_RemoveKey( char *s, const char *key ); +extern const char *mm_GetPhysicsKeyValue( const edict_t *pClient, const char *key ); +extern void mm_SetPhysicsKeyValue( const edict_t *pClient, const char *key, const char *value ); +extern const char *mm_GetPhysicsInfoString( const edict_t *pClient ); +extern unsigned short mm_PrecacheEvent( int type, const char *psz ); +extern void mm_PlaybackEvent( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); + +extern unsigned char *mm_SetFatPVS( float *org ); +extern unsigned char *mm_SetFatPAS( float *org ); + +extern int mm_CheckVisibility( const edict_t *entity, unsigned char *pset ); + +extern void mm_DeltaSetField( struct delta_s *pFields, const char *fieldname ); +extern void mm_DeltaUnsetField( struct delta_s *pFields, const char *fieldname ); +extern void mm_DeltaAddEncoder( char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) ); +extern int mm_GetCurrentPlayer( void ); +extern int mm_CanSkipPlayer( const edict_t *player ); +extern int mm_DeltaFindField( struct delta_s *pFields, const char *fieldname ); +extern void mm_DeltaSetFieldByIndex( struct delta_s *pFields, int fieldNumber ); +extern void mm_DeltaUnsetFieldByIndex( struct delta_s *pFields, int fieldNumber ); + +extern void mm_SetGroupMask( int mask, int op ); + +extern int CreateInstancedBaseline( int classname, struct entity_state_s *baseline ); +extern void mm_Cvar_DirectSet( struct cvar_s *var, char *value ); + +//! Forces the client and server to be running with the same version of the specified file +//!( e.g., a player model ). +//! Calling this has no effect in single player +extern void mm_ForceUnmodified( FORCE_TYPE type, float *mins, float *maxs, const char *filename ); + +extern void mm_GetPlayerStats( const edict_t *pClient, int *ping, int *packet_loss ); + +extern void mm_AddServerCommand( char *cmd_name, void (*function) (void) ); +// Added in SDK 2.2: +extern qboolean mm_Voice_GetClientListening(int iReceiver, int iSender); +extern qboolean mm_Voice_SetClientListening(int iReceiver, int iSender, qboolean bListen); +// Added for HL 1109 (no SDK update): +extern const char *mm_pfnGetPlayerAuthId(edict_t *e); +// Added 2003-11-10 (no SDK update): +extern sequenceEntry_s * mm_SequenceGet(const char* fileName, const char* entryName); +extern sentenceEntry_s * mm_SequencePickSentence(const char* groupName, int pickMethod, int *picked); +extern int mm_GetFileSize(char *filename); +extern unsigned int mm_GetApproxWavePlayLen(const char *filepath); +extern int mm_IsCareerMatch(void); +extern int mm_GetLocalizedStringLength(const char *label); +extern void mm_RegisterTutorMessageShown(int mid); +extern int mm_GetTimesTutorMessageShown(int mid); +extern void mm_ProcessTutorMessageDecayBuffer(int *buffer, int bufferLength); +extern void mm_ConstructTutorMessageDecayBuffer(int *buffer, int bufferLength); +extern void mm_ResetTutorMessageDecayData(void); +//Added 2005-08-11 (no SDK update) +extern void mm_QueryClientCvarValue(const edict_t *pEdict, const char *cvarName); //! Obsolete! Use mm_QueryClientCvarValue2 instead +//Added 2005-11-22 (no SDK update) +extern void mm_QueryClientCvarValue2(const edict_t *pEdict, const char *cvarName, int requestID); + + +// Typedefs for the above functions: + +typedef int (*FN_PRECACHEMODEL) (char* s); +typedef int (*FN_PRECACHESOUND) (char* s); +typedef void (*FN_SETMODEL) (edict_t *e, const char *m); +typedef int (*FN_MODELINDEX) (const char *m); +typedef int (*FN_MODELFRAMES) (int modelIndex); +typedef void (*FN_SETSIZE) (edict_t *e, const float *rgflMin, const float *rgflMax); +typedef void (*FN_CHANGELEVEL) (char *s1, char *s2); +typedef void (*FN_GETSPAWNPARMS) (edict_t *ent); +typedef void (*FN_SAVESPAWNPARMS) (edict_t *ent); +typedef float (*FN_VECTOYAW) (const float *rgflVector); +typedef void (*FN_VECTOANGLES) (const float *rgflVectorIn, float *rgflVectorOut); +typedef void (*FN_MOVETOORIGIN) (edict_t *ent, const float *pflGoal, float dist, int iMoveType); +typedef void (*FN_CHANGEYAW) (edict_t *ent); +typedef void (*FN_CHANGEPITCH) (edict_t *ent); +typedef edict_t * (*FN_FINDENTITYBYSTRING) (edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue); +typedef int (*FN_GETENTITYILLUM) (edict_t *pEnt); +typedef edict_t * (*FN_FINDENTITYINSPHERE) (edict_t *pEdictStartSearchAfter, const float *org, float rad); +typedef edict_t * (*FN_FINDCLIENTINPVS) (edict_t *pEdict); +typedef edict_t * (*FN_ENTITIESINPVS) (edict_t *pplayer); +typedef void (*FN_MAKEVECTORS) (const float *rgflVector); +typedef void (*FN_ANGLEVECTORS) (const float *rgflVector, float *forward, float *right, float *up); +typedef edict_t * (*FN_CREATEENTITY) (void); +typedef void (*FN_REMOVEENTITY) (edict_t *e); +typedef edict_t * (*FN_CREATENAMEDENTITY) (int className); +typedef void (*FN_MAKESTATIC) (edict_t *ent); +typedef int (*FN_ENTISONFLOOR) (edict_t *e); +typedef int (*FN_DROPTOFLOOR) (edict_t *e); +typedef int (*FN_WALKMOVE) (edict_t *ent, float yaw, float dist, int iMode); +typedef void (*FN_SETORIGIN) (edict_t *e, const float *rgflOrigin); +typedef void (*FN_EMITSOUND) (edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch); +typedef void (*FN_EMITAMBIENTSOUND) (edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch); +typedef void (*FN_TRACELINE) (const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); +typedef void (*FN_TRACETOSS) (edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr); +typedef int (*FN_TRACEMONSTERHULL) (edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); +typedef void (*FN_TRACEHULL) (const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr); +typedef void (*FN_TRACEMODEL) (const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr); +typedef const char * (*FN_TRACETEXTURE) (edict_t *pTextureEntity, const float *v1, const float *v2 ); +typedef void (*FN_TRACESPHERE) (const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr); +typedef void (*FN_GETAIMVECTOR) (edict_t *ent, float speed, float *rgflReturn); +typedef void (*FN_SERVERCOMMAND) (char *str); +typedef void (*FN_SERVEREXECUTE) (void); +typedef void (*FN_CLIENTCOMMAND_ENG) (edict_t *pEdict, char *szFmt, ...); +typedef void (*FN_PARTICLEEFFECT) (const float *org, const float *dir, float color, float count); +typedef void (*FN_LIGHTSTYLE) (int style, char *val); +typedef int (*FN_DECALINDEX) (const char *name); +typedef int (*FN_POINTCONTENTS) (const float *rgflVector); +typedef void (*FN_MESSAGEBEGIN) (int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); +typedef void (*FN_MESSAGEEND) (void); +typedef void (*FN_WRITEBYTE) (int iValue); +typedef void (*FN_WRITECHAR) (int iValue); +typedef void (*FN_WRITESHORT) (int iValue); +typedef void (*FN_WRITELONG) (int iValue); +typedef void (*FN_WRITEANGLE) (float flValue); +typedef void (*FN_WRITECOORD) (float flValue); +typedef void (*FN_WRITESTRING) (const char *sz); +typedef void (*FN_WRITEENTITY) (int iValue); +typedef void (*FN_CVARREGISTER) (cvar_t *pCvar); +typedef float (*FN_CVARGETFLOAT) (const char *szVarName); +typedef const char * (*FN_CVARGETSTRING) (const char *szVarName); +typedef void (*FN_CVARSETFLOAT) (const char *szVarName, float flValue); +typedef void (*FN_CVARSETSTRING) (const char *szVarName, const char *szValue); +typedef void (*FN_ALERTMESSAGE) (ALERT_TYPE atype, char *szFmt, ...); +#ifdef HLSDK_3_2_OLD_EIFACE +typedef void (*FN_ENGINEFPRINTF) (FILE *pfile, char *szFmt, ...); +typedef void * (*FN_PVALLOCENTPRIVATEDATA) (edict_t *pEdict, long cb); +#else +typedef void (*FN_ENGINEFPRINTF) (void *pfile, char *szFmt, ...); +typedef void * (*FN_PVALLOCENTPRIVATEDATA) (edict_t *pEdict, int32 cb); +#endif +typedef void * (*FN_PVENTPRIVATEDATA) (edict_t *pEdict); +typedef void (*FN_FREEENTPRIVATEDATA) (edict_t *pEdict); +typedef const char * (*FN_SZFROMINDEX) (int iString); +typedef int (*FN_ALLOCSTRING) (const char *szValue); +typedef struct entvars_s * (*FN_GETVARSOFENT) (edict_t *pEdict); +typedef edict_t * (*FN_PENTITYOFENTOFFSET) (int iEntOffset); +typedef int (*FN_ENTOFFSETOFPENTITY) (const edict_t *pEdict); +typedef int (*FN_INDEXOFEDICT) (const edict_t *pEdict); +typedef edict_t * (*FN_PENTITYOFENTINDEX) (int iEntIndex); +typedef edict_t * (*FN_FINDENTITYBYVARS) (struct entvars_s *pvars); +typedef void * (*FN_GETMODELPTR) (edict_t *pEdict); +typedef int (*FN_REGUSERMSG) (const char *pszName, int iSize); +typedef void (*FN_ANIMATIONAUTOMOVE) (const edict_t *pEdict, float flTime); +typedef void (*FN_GETBONEPOSITION) (const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles ); +#ifdef HLSDK_3_2_OLD_EIFACE +typedef unsigned long (*FN_FUNCTIONFROMNAME) ( const char *pName ); +typedef const char * (*FN_NAMEFORFUNCTION) ( unsigned long function ); +#else +typedef uint32 (*FN_FUNCTIONFROMNAME) ( const char *pName ); +typedef const char * (*FN_NAMEFORFUNCTION) ( uint32 function ); +#endif +typedef void (*FN_CLIENTPRINTF) ( edict_t *pEdict, PRINT_TYPE ptype, const char *szMsg ); +typedef void (*FN_SERVERPRINT) ( const char *szMsg ); +typedef const char * (*FN_CMD_ARGS) ( void ); +typedef const char * (*FN_CMD_ARGV) ( int argc ); +typedef int (*FN_CMD_ARGC) ( void ); +typedef void (*FN_GETATTACHMENT) (const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles ); +typedef void (*FN_CRC32_INIT) (CRC32_t *pulCRC); +typedef void (*FN_CRC32_PROCESSBUFFER) (CRC32_t *pulCRC, void *p, int len); +typedef void (*FN_CRC32_PROCESSBYTE) (CRC32_t *pulCRC, unsigned char ch); +typedef CRC32_t (*FN_CRC32_FINAL) (CRC32_t pulCRC); +#ifdef HLSDK_3_2_OLD_EIFACE +typedef long (*FN_RANDOMLONG) (long lLow, long lHigh); +#else +typedef int32 (*FN_RANDOMLONG) (int32 lLow, int32 lHigh); +#endif +typedef float (*FN_RANDOMFLOAT) (float flLow, float flHigh); +typedef void (*FN_SETVIEW) (const edict_t *pClient, const edict_t *pViewent ); +typedef float (*FN_TIME) ( void ); +typedef void (*FN_CROSSHAIRANGLE) (const edict_t *pClient, float pitch, float yaw); +typedef byte * (*FN_LOADFILEFORME) (char *filename, int *pLength); +typedef void (*FN_FREEFILE) (void *buffer); +typedef void (*FN_ENDSECTION) (const char *pszSectionName); +typedef int (*FN_COMPAREFILETIME) (char *filename1, char *filename2, int *iCompare); +typedef void (*FN_GETGAMEDIR) (char *szGetGameDir); +typedef void (*FN_CVAR_REGISTERVARIABLE) (cvar_t *variable); +typedef void (*FN_FADECLIENTVOLUME) (const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds); +typedef void (*FN_SETCLIENTMAXSPEED) (const edict_t *pEdict, float fNewMaxspeed); +typedef edict_t * (*FN_CREATEFAKECLIENT) (const char *netname); +typedef void (*FN_RUNPLAYERMOVE) (edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec ); +typedef int (*FN_NUMBEROFENTITIES) (void); +typedef char * (*FN_GETINFOKEYBUFFER) (edict_t *e); +typedef char * (*FN_INFOKEYVALUE) (char *infobuffer, char *key); +typedef void (*FN_SETKEYVALUE) (char *infobuffer, char *key, char *value); +typedef void (*FN_SETCLIENTKEYVALUE) (int clientIndex, char *infobuffer, char *key, char *value); +typedef int (*FN_ISMAPVALID) (char *filename); +typedef void (*FN_STATICDECAL) ( const float *origin, int decalIndex, int entityIndex, int modelIndex ); +typedef int (*FN_PRECACHEGENERIC) (char *s); +typedef int (*FN_GETPLAYERUSERID) (edict_t *e ); +typedef void (*FN_BUILDSOUNDMSG) (edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); +typedef int (*FN_ISDEDICATEDSERVER) (void); +typedef cvar_t * (*FN_CVARGETPOINTER) (const char *szVarName); +typedef unsigned int (*FN_GETPLAYERWONID) (edict_t *e); +typedef void (*FN_INFO_REMOVEKEY) ( char *s, const char *key ); +typedef const char * (*FN_GETPHYSICSKEYVALUE) ( const edict_t *pClient, const char *key ); +typedef void (*FN_SETPHYSICSKEYVALUE) ( const edict_t *pClient, const char *key, const char *value ); +typedef const char * (*FN_GETPHYSICSINFOSTRING) ( const edict_t *pClient ); +typedef unsigned short (*FN_PRECACHEEVENT) ( int type, const char *psz ); +typedef void (*FN_PLAYBACKEVENT) ( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); +typedef unsigned char * (*FN_SETFATPVS) ( float *org ); +typedef unsigned char * (*FN_SETFATPAS) ( float *org ); +typedef int (*FN_CHECKVISIBILITY) ( const edict_t *entity, unsigned char *pset ); +typedef void (*FN_DELTASETFIELD) ( struct delta_s *pFields, const char *fieldname ); +typedef void (*FN_DELTAUNSETFIELD) ( struct delta_s *pFields, const char *fieldname ); +typedef void (*FN_DELTAADDENCODER) ( char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) ); +typedef int (*FN_GETCURRENTPLAYER) ( void ); +typedef int (*FN_CANSKIPPLAYER) ( const edict_t *player ); +typedef int (*FN_DELTAFINDFIELD) ( struct delta_s *pFields, const char *fieldname ); +typedef void (*FN_DELTASETFIELDBYINDEX) ( struct delta_s *pFields, int fieldNumber ); +typedef void (*FN_DELTAUNSETFIELDBYINDEX) ( struct delta_s *pFields, int fieldNumber ); +typedef void (*FN_SETGROUPMASK) ( int mask, int op ); +typedef int (*FN_CREATEINSTANCEDBASELINE) ( int classname, struct entity_state_s *baseline ); +typedef void (*FN_CVAR_DIRECTSET) ( struct cvar_s *var, char *value ); +typedef void (*FN_FORCEUNMODIFIED) ( FORCE_TYPE type, float *mins, float *maxs, const char *filename ); +typedef void (*FN_GETPLAYERSTATS) ( const edict_t *pClient, int *ping, int *packet_loss ); +typedef void (*FN_ADDSERVERCOMMAND) ( char *cmd_name, void (*function) (void) ); +// Added in SDK 2.2: +typedef qboolean (*FN_VOICE_GETCLIENTLISTENING) (int iReceiver, int iSender); +typedef qboolean (*FN_VOICE_SETCLIENTLISTENING) (int iReceiver, int iSender, qboolean bListen); +// Added for HL 1109 (no SDK update): +typedef const char * (*FN_GETPLAYERAUTHID) (edict_t *e); +// Added 2003-11-10 (no SDK update): +typedef sequenceEntry_s * (*FN_SEQUENCEGET) (const char* fileName, const char* entryName); +typedef sentenceEntry_s * (*FN_SEQUENCEPICKSENTENCE) (const char* groupName, int pickMethod, int *picked); +typedef int (*FN_GETFILESIZE) (char *filename); +typedef unsigned int (*FN_GETAPPROXWAVEPLAYLEN) (const char *filepath); +typedef int (*FN_ISCAREERMATCH) (void); +typedef int (*FN_GETLOCALIZEDSTRINGLENGTH) (const char *label); +typedef void (*FN_REGISTERTUTORMESSAGESHOWN) (int mid); +typedef int (*FN_GETTIMESTUTORMESSAGESHOWN) (int mid); +typedef void (*FN_PROCESSTUTORMESSAGEDECAYBUFFER) (int *buffer, int bufferLength); +typedef void (*FN_CONSTRUCTTUTORMESSAGEDECAYBUFFER) (int *buffer, int bufferLength); +typedef void (*FN_RESETTUTORMESSAGEDECAYDATA) (void); +//Added 2005-08-11 (no SDK update) +typedef void (*FN_QUERYCLIENTCVARVALUE)(const edict_t *pEdict, const char *cvarName); //! Obsolete! Use FN_QUERYCLIENTCVARVALUE2 instead +//Added 2005-11-22 (no SDK update) +typedef void (*FN_QUERYCLIENTCVARVALUE2)(const edict_t *pEdict, const char *cvarName, int requestID); + +#endif /* ENGINE_API_H */ diff --git a/sdk/metamod/engine_t.h b/sdk/metamod/engine_t.h new file mode 100644 index 0000000..04149b1 --- /dev/null +++ b/sdk/metamod/engine_t.h @@ -0,0 +1,81 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// engine_t.h - The engine_t type + +/* + * Copyright (c) 2001-2006 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MM_ENGINE_T_H +#define MM_ENGINE_T_H + +#include "eiface.h" // engfuncs_t, globalvars_t +#include "engineinfo.h" // EngineInfo + + +// Our structure for storing engine references. +struct engine_t { + engine_t(); + engine_t(const engine_t&); + engine_t& operator=(const engine_t&); + + enginefuncs_t *funcs; // engine funcs + globalvars_t *globals; // engine globals + enginefuncs_t *pl_funcs; // "modified" eng funcs we give to plugins + EngineInfo info; // some special info elements +}; + +inline engine_t::engine_t() + : funcs(NULL), globals(NULL), pl_funcs(NULL), info() +{ +} + + +inline engine_t::engine_t(const engine_t& _rhs) + : funcs(_rhs.funcs), globals(_rhs.globals), pl_funcs(_rhs.pl_funcs), info(_rhs.info) +{ +} + + +inline engine_t& engine_t::operator=(const engine_t& _rhs) +{ + funcs = _rhs.funcs; + globals = _rhs.globals; + pl_funcs = _rhs.pl_funcs; + info = _rhs.info; + return *this; +} + + +extern engine_t Engine; + +#endif /* MM_ENGINE_T_H */ + diff --git a/sdk/metamod/enginecallbacks.h b/sdk/metamod/enginecallbacks.h new file mode 100644 index 0000000..59a1f0b --- /dev/null +++ b/sdk/metamod/enginecallbacks.h @@ -0,0 +1,78 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// enginecallbacks.h - wrapper for + +/* + * Copyright (c) 2001-2006 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MM_ENGINECALLBACKS_H +#define MM_ENGINECALLBACKS_H + +// This file is a wrapper around the SDK's enginecallback.h file. We need +// this because we use a different type for the global object g_engfuncs, +// which is still compatible with the enginefuncs_t that the SDK +// uses. +// This is only done for files that belong to Metamod, not other projects +// like plugins that use this file, or others that include it, too. +// Since we don't have a clean seperation of include files right now we +// "hack" our way around that by using a flag METAMOD_CORE which is set +// when compiling Metamod proper. + +#ifdef METAMOD_CORE +# include "meta_eiface.h" // HL_enginefuncs_t + +// Use a #define to bend the enginefuncs_t type to our HL_enginefuncs_t +// type instead as we now use that for the global object g_engfuncs. +# define enginefuncs_t HL_enginefuncs_t +#endif /* METAMOD_CORE */ + +#include // ALERT, etc + +#ifdef METAMOD_CORE +# undef enginefuncs_t +#endif /* METAMOD_CORE */ + +// Also, create some additional macros for engine callback functions, which +// weren't in SDK dlls/enginecallbacks.h but probably should have been. + +#define GET_INFOKEYBUFFER (*g_engfuncs.pfnGetInfoKeyBuffer) +#define INFOKEY_VALUE (*g_engfuncs.pfnInfoKeyValue) +#define SET_CLIENT_KEYVALUE (*g_engfuncs.pfnSetClientKeyValue) +#define REG_SVR_COMMAND (*g_engfuncs.pfnAddServerCommand) +#define SERVER_PRINT (*g_engfuncs.pfnServerPrint) +#define SET_SERVER_KEYVALUE (*g_engfuncs.pfnSetKeyValue) +#define QUERY_CLIENT_CVAR_VALUE (*g_engfuncs.pfnQueryClientCvarValue) +#define QUERY_CLIENT_CVAR_VALUE2 (*g_engfuncs.pfnQueryClientCvarValue2) + + +#endif /* MM_ENGINECALLBACKS_H */ + diff --git a/sdk/metamod/engineinfo.h b/sdk/metamod/engineinfo.h new file mode 100644 index 0000000..2937ff3 --- /dev/null +++ b/sdk/metamod/engineinfo.h @@ -0,0 +1,255 @@ + +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// engineinfo.h - info about HL engine, like file used and +// text segment range +// + +#ifndef MM_ENGINEINFO_H +#define MM_ENGINEINFO_H + + + +#ifdef _WIN32 +typedef void* MemAddr; +#else +# include // ElfW(Addr/Phdr) macros +typedef void* MemAddr; +#endif /* _WIN32 */ + +#include "extdll.h" // eiface.h: enginefuncs_t + + +// What we return in is_valid_code_pointer() when the EngineInfo object is +// in an INVALID state, i.e. no code address range could be determined. +static const bool c_DefaultReturnOnInvalidState = true; + +static const int c_EngineInfo__typeLen = 10; + + +class EngineInfo +{ + private: + // data : + + MemAddr m_codeStart; + MemAddr m_codeEnd; + + // State is either NULL when not yet initialised, + // VALID if a code range could be determined + // or INVALID when no valid range for code addresses + // could be determined. + char m_state; + + // Type of engine dso/dll used. + // For Linux this specifies the architecture, i.e. 'i486', 'i686', + // 'amd', 'amd64' etc. + // For Windows this is either 'sw' or 'hw' or 'swds' depending on + // the server type. + char m_type[c_EngineInfo__typeLen]; + + // functions : + + + // Check if string is valid name of engine dso/dll. + bool check_for_engine_module( const char* pName ); + +#ifdef _WIN32 + + // Set info using the PE header found by module name. + // Returns 0 on success, error code on failure. + int nthdr_module_name( void ); + + int vac_pe_approx( enginefuncs_t* pFuncs ); + + // Set code segment start and end from PEheader. The base + // address, that relative addresses are based on, is passed in + // pBase. + void set_code_range( unsigned char* pBase, PIMAGE_NT_HEADERS pNThdr ); + +#else + + // Set info using the Programheader found via r_debug struct. + // Returns 0 on success, error code on failure. + int phdr_r_debug( void ); + // Set info using the Programheader found with reference address + // via dladdr(). Returns 0 on success, error code on failure. + int phdr_dladdr( void* pMem ); + // Set info using the Programheader found via ELF header passed as + // pElfHdr. Return 0 on success, error code on failure. + int phdr_elfhdr( void* pElfHdr ); + // Set code segment start and end from Programheader. The base + // address, that relative addresses are based on, is passed in + // pBase. + void set_code_range( void* pBase, ElfW(Phdr)* pPhdr ); + +#endif /* _WIN32 */ + + public: + // codes : + + enum { + STATE_NULL = 0, + STATE_VALID, + STATE_INVALID, + + MODULE_NAME_NOTFOUND = 5, + INVALID_DOS_SIGN, + INVALID_NT_SIGN, + INVALID_ARG, + HEADER_NOTFOUND, + NOTFOUND + }; + + + // functions : + + EngineInfo(); + EngineInfo& operator=( const EngineInfo& ); + EngineInfo( const EngineInfo& ); + + const char* type( void ); + + // Initilaise object, determining the bounds of the code segment of + // the HL engine shared object. + int initialise( enginefuncs_t* pFuncs = NULL ); + + // Test if pMem is within bounds of the code segment. + bool is_valid_code_pointer( void* pMem ); + + // Overloaded versions of above test to keep the ugly pointer + // conversion stuff in here. + bool is_valid_code_pointer( const char* (*fp) (edict_t*) ); + bool is_valid_code_pointer( sequenceEntry_s* (*fp) (const char*, const char*) ); + bool is_valid_code_pointer( sentenceEntry_s* (*fp) (const char*, int, int*) ); + bool is_valid_code_pointer( int (*fp) (char*) ); + bool is_valid_code_pointer( unsigned int (*fp) (const char*) ); + bool is_valid_code_pointer( int (*fp) (void) ); + bool is_valid_code_pointer( int (*fp) (const char*) ); + bool is_valid_code_pointer( void (*fp) (int) ); + bool is_valid_code_pointer( int (*fp) (int) ); + bool is_valid_code_pointer( void (*fp) (int*, int) ); + bool is_valid_code_pointer( void (*fp) (void) ); + bool is_valid_code_pointer( void (*fp) (const edict_t*, const char*) ); + bool is_valid_code_pointer( void (*fp) (const edict_t*, const char*, int) ); + + +}; + + + +// We probably should run an initialisation here without a reference +// pointer so that the object has valid info in any case. +inline EngineInfo::EngineInfo() : + m_codeStart(NULL), + m_codeEnd(NULL), + m_state(STATE_NULL) +{ + m_type[0] = '\0'; +} + + +inline EngineInfo::EngineInfo( const EngineInfo& _rhs) : + m_codeStart(_rhs.m_codeStart), + m_codeEnd(_rhs.m_codeEnd), + m_state(STATE_NULL) +{ + memcpy( m_type, _rhs.m_type, c_EngineInfo__typeLen ); +} + + +inline EngineInfo& EngineInfo::operator=( const EngineInfo& _rhs) +{ + m_state = _rhs.m_state; + m_codeStart = _rhs.m_codeStart; + m_codeEnd = _rhs.m_codeEnd; + memcpy( m_type, _rhs.m_type, c_EngineInfo__typeLen ); + return *this; +} + + +inline const char* EngineInfo::type( void ) +{ + return m_type; +} + +inline bool EngineInfo::is_valid_code_pointer( void* _pMem ) +{ + if ( STATE_INVALID == m_state ) { + return c_DefaultReturnOnInvalidState; + } + if ( NULL != _pMem && m_codeStart <= _pMem && _pMem <= m_codeEnd ) { + return true; + } + + return false; +} + +inline bool EngineInfo::is_valid_code_pointer( const char* (*_fp) (edict_t*) ) +{ + return is_valid_code_pointer( (void*)_fp ); +} + +inline bool EngineInfo::is_valid_code_pointer( sequenceEntry_s* (*_fp) (const char*, const char*) ) +{ + return is_valid_code_pointer( (void*)_fp ); +} + +inline bool EngineInfo::is_valid_code_pointer( sentenceEntry_s* (*_fp) (const char*, int, int*) ) +{ + return is_valid_code_pointer( (void*)_fp ); +} + +inline bool EngineInfo::is_valid_code_pointer( int (*_fp) (char*) ) +{ + return is_valid_code_pointer( (void*)_fp ); +} + +inline bool EngineInfo::is_valid_code_pointer( unsigned int (*_fp) (const char*) ) +{ + return is_valid_code_pointer( (void*)_fp ); +} + +inline bool EngineInfo::is_valid_code_pointer( int (*_fp) (void) ) +{ + return is_valid_code_pointer( (void*)_fp ); +} + +inline bool EngineInfo::is_valid_code_pointer( int (*_fp) (const char*) ) +{ + return is_valid_code_pointer( (void*)_fp ); +} + +inline bool EngineInfo::is_valid_code_pointer( void (*_fp) (int) ) +{ + return is_valid_code_pointer( (void*)_fp ); +} + +inline bool EngineInfo::is_valid_code_pointer( int (*_fp) (int) ) +{ + return is_valid_code_pointer( (void*)_fp ); +} + +inline bool EngineInfo::is_valid_code_pointer( void (*_fp) (int*, int) ) +{ + return is_valid_code_pointer( (void*)_fp ); +} + +inline bool EngineInfo::is_valid_code_pointer( void (*_fp) (void) ) +{ + return is_valid_code_pointer( (void*)_fp ); +} + +inline bool EngineInfo::is_valid_code_pointer( void (*_fp) (const edict_t*, const char*) ) +{ + return is_valid_code_pointer( (void*)_fp ); +} + +inline bool EngineInfo::is_valid_code_pointer( void (*_fp) (const edict_t*, const char*, int) ) +{ + return is_valid_code_pointer( (void*)_fp ); +} + +#endif /* MM_ENGINEINFO_H */ + diff --git a/sdk/metamod/game_support.h b/sdk/metamod/game_support.h new file mode 100644 index 0000000..134fda0 --- /dev/null +++ b/sdk/metamod/game_support.h @@ -0,0 +1,55 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// game_support.h - structures for supporting different HL mod "games" + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef GAME_SUPPORT_H +#define GAME_SUPPORT_H + +#include "types_meta.h" // mBOOL +#include "metamod.h" // gamedll_t + +// Information we have about each game/mod DLL. +typedef struct game_modinfo_s { + char *name; // name (the game dir) + char *linux_so; // filename of linux shared lib + char *win_dll; // filename of win32 dll + char *desc; // our long-name description +} game_modinfo_t; + +typedef game_modinfo_t game_modlist_t[]; +game_modinfo_t *lookup_game(const char *name); +mBOOL setup_gamedll(gamedll_t *gamedll); + +#endif /* GAME_SUPPORT_H */ diff --git a/sdk/metamod/games.h b/sdk/metamod/games.h new file mode 100644 index 0000000..59cf7c4 --- /dev/null +++ b/sdk/metamod/games.h @@ -0,0 +1,130 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// games.h - list of supported game mods and their data + +/* + * Copyright (c) 2001-2006 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +// This list is now kept in a separate file to facilitate generating the +// list from game data stored in a convenient db. + +#ifdef __amd64__ +# define MODARCH "_amd64" +#else +# define MODARCH "_i386" +#endif + + {"action", "ahl"MODARCH".so", "ahl.dll", "Action Half-Life"}, + {"ag", "ag"MODARCH".so", "ag.dll", "Adrenaline Gamer Steam"}, + {"ag3", "hl"MODARCH".so", "hl.dll", "Adrenalinegamer 3.x"}, + {"aghl", "ag"MODARCH".so", "ag.dll", "Adrenalinegamer 4.x"}, + {"arg", "arg"MODARCH".so", "hl.dll", "Arg!"}, + {"asheep", "hl"MODARCH".so", "hl.dll", "Azure Sheep"}, + {"bg", "bg"MODARCH".so", "bg.dll", "The Battle Grounds"}, + {"bot", "bot"MODARCH".so", "bot.dll", "Bot"}, + {"brainbread", "bb"MODARCH".so", "bb.dll", "Brain Bread"}, + {"bumpercars", "hl"MODARCH".so", "hl.dll", "Bumper Cars"}, + {"buzzybots", "bb"MODARCH".so", "bb.dll", "BuzzyBots"}, + {"cs13", "cs"MODARCH".so", "mp.dll", "Counter-Strike 1.3"}, + {"cstrike", "cs"MODARCH".so", "mp.dll", "Counter-Strike"}, + {"csv15", "cs"MODARCH".so", "mp.dll", "CS 1.5 for Steam"}, + {"czero", "cs"MODARCH".so", "mp.dll", "Counter-Strike:Condition Zero"}, + {"dcrisis", "dc"MODARCH".so", "dc.dll", "Desert Crisis"}, + {"dmc", "dmc"MODARCH".so", "dmc.dll", "Deathmatch Classic"}, + {"dod", "dod"MODARCH".so", "dod.dll", "Day of Defeat"}, + {"dpb", "pb.i386.so", "pb.dll", "Digital Paintball"}, + {"dragonmodz", "hl"MODARCH".so", "mp.dll", "Dragon Mod Z"}, + {"esf", "hl"MODARCH".so", "hl.dll", "Earth's Special Forces"}, + {"existence", "ex"MODARCH".so", "existence.dll", "Existence"}, + {"firearms", "fa"MODARCH".so", "firearms.dll", "Firearms"}, + {"firearms25", "fa"MODARCH".so", "firearms.dll", "Retro Firearms"}, + {"freeze", "mp"MODARCH".so", "mp.dll", "Freeze"}, + {"frontline", "front"MODARCH".so", "frontline.dll", "Frontline Force"}, + {"gangstawars", "gangsta"MODARCH".so", "gwars27.dll", "Gangsta Wars"}, + {"gangwars", "mp"MODARCH".so", "mp.dll", "Gangwars"}, + {"gearbox", "opfor"MODARCH".so", "opfor.dll", "Opposing Force"}, + {"globalwarfare", "gw"MODARCH".so", "mp.dll", "Global Warfare"}, + {"goldeneye", "golden"MODARCH".so", "mp.dll", "Goldeneye"}, + {"hlrally", "hlr"MODARCH".so", "hlrally.dll", "HL-Rally"}, + {"holywars", "hl"MODARCH".so", "holywars.dll", "Holy Wars"}, + {"hostileintent", "hl"MODARCH".so", "hl.dll", "Hostile Intent"}, + {"ios", "ios"MODARCH".so", "ios.dll", "International Online Soccer"}, + {"judgedm", "judge"MODARCH".so", "mp.dll", "Judgement"}, + {"kanonball", "hl"MODARCH".so", "kanonball.dll", "Kanonball"}, + {"monkeystrike", "ms"MODARCH".so", "monkey.dll", "Monkeystrike"}, + {"MorbidPR", "morbid"MODARCH".so", "morbid.dll", "Morbid Inclination"}, + {"movein", "hl"MODARCH".so", "hl.dll", "Move In!"}, + {"ns", "ns"MODARCH".so", "ns.dll", "Natural Selection"}, + {"nsp", "ns"MODARCH".so", "ns.dll", "Natural Selection Beta"}, + {"oel", "hl"MODARCH".so", "hl.dll", "OeL Half-Life"}, + {"og", "og"MODARCH".so", "og.dll", "Over Ground"}, + {"ol", "ol"MODARCH".so", "hl.dll", "Outlawsmod"}, + {"ops1942", "spirit"MODARCH".so", "spirit.dll", "Operations 1942"}, + {"osjb", "osjb"MODARCH".so", "jail.dll", "Open-Source Jailbreak"}, + {"outbreak", "none", "hl.dll", "Out Break"}, + {"oz", "mp"MODARCH".so", "mp.dll", "Oz Deathmatch"}, + {"paintball", "pb"MODARCH".so", "mp.dll", "Paintball"}, + {"penemy", "pe"MODARCH".so", "pe.dll", "Public Enemy"}, + {"phineas", "phineas"MODARCH".so", "phineas.dll", "Phineas Bot"}, + {"ponreturn", "ponr"MODARCH".so", "mp.dll", "Point of No Return"}, + {"pvk", "hl"MODARCH".so", "hl.dll", "Pirates, Vikings and Knights"}, + {"rc2", "rc2"MODARCH".so", "rc2.dll", "Rocket Crowbar 2"}, + {"retrocs", "rcs"MODARCH".so", "rcs.dll", "Retro Counter-Strike"}, + {"rewolf", "hl"MODARCH".so", "gunman.dll", "Gunman Chronicles"}, + {"ricochet", "ricochet"MODARCH".so", "mp.dll", "Ricochet"}, + {"rockcrowbar", "rc"MODARCH".so", "rc.dll", "Rocket Crowbar"}, + {"rspecies", "hl"MODARCH".so", "hl.dll", "Rival Species"}, + {"scihunt", "shunt.so", "shunt.dll", "Scientist Hunt"}, + {"sdmmod", "sdmmod"MODARCH".so", "sdmmod.dll", "Special Death Match"}, + {"Ship", "ship"MODARCH".so", "ship.dll", "The Ship"}, + {"si", "si"MODARCH".so", "si.dll", "Science & Industry"}, + {"snow", "snow"MODARCH".so", "snow.dll", "Snow-War"}, + {"stargatetc", "hl"MODARCH".so", "hl.dll", "StargateTC"}, + {"svencoop", "hl"MODARCH".so", "hl.dll", "Sven Coop"}, + {"swarm", "swarm"MODARCH".so", "swarm.dll", "Swarm"}, + {"tfc", "tfc"MODARCH".so", "tfc.dll", "Team Fortress Classic"}, + {"thewastes", "thewastes"MODARCH".so", "thewastes.dll", "The Wastes"}, + {"timeless", "pt"MODARCH".so", "timeless.dll", "Project Timeless"}, + {"tod", "hl"MODARCH".so", "hl.dll", "Tour of Duty"}, + {"trainhunters", "th"MODARCH".so", "th.dll", "Train Hunters"}, + {"trevenge", "trevenge.so", "trevenge.dll", "The Terrorist Revenge"}, + {"TS", "ts"MODARCH".so", "mp.dll", "The Specialists"}, + {"tt", "tt"MODARCH".so", "tt.dll", "The Trenches"}, + {"underworld", "uw"MODARCH".so", "uw.dll", "Underworld Bloodline"}, + {"valve", "hl"MODARCH".so", "hl.dll", "Half-Life Deathmatch"}, + {"vs", "vs"MODARCH".so", "mp.dll", "VampireSlayer"}, + {"wantedhl", "hl"MODARCH".so", "wanted.dll", "Wanted!"}, + {"wasteland", "whl_linux.so", "mp.dll", "Wasteland"}, + {"weapon_wars", "ww"MODARCH".so", "hl.dll", "Weapon Wars"}, + {"wizwars", "mp"MODARCH".so", "hl.dll", "Wizard Wars"}, + {"wormshl", "wormshl_i586.so", "wormshl.dll", "WormsHL"}, + {"zp", "none", "mp.dll", "Zombie Panic"}, diff --git a/sdk/metamod/h_export.h b/sdk/metamod/h_export.h new file mode 100644 index 0000000..a9e64a9 --- /dev/null +++ b/sdk/metamod/h_export.h @@ -0,0 +1,49 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// h_export.h - prototypes for h_export.cpp + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef H_EXPORT_H +#define H_EXPORT_H + +#include "osdep.h" // DLLEXPORT, WINAPI, etc + +// Our GiveFnptrsToDll, called by engine. +typedef void (WINAPI *GIVE_ENGINE_FUNCTIONS_FN) (enginefuncs_t + *pengfuncsFromEngine, globalvars_t *pGlobals); + +C_DLLEXPORT void WINAPI GiveFnptrsToDll(enginefuncs_t *pengfuncsFromEngine, + globalvars_t *pGlobals); + +#endif /* H_EXPORT_H */ diff --git a/sdk/metamod/info_name.h b/sdk/metamod/info_name.h new file mode 100644 index 0000000..1605cfe --- /dev/null +++ b/sdk/metamod/info_name.h @@ -0,0 +1,56 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// info_name.h - name, desc, author, etc + +/* + * Copyright (c) 2001-2004 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef INFO_NAME_H +#define INFO_NAME_H + +#include "vers_meta.h" // VDATE, VVERSION, etc + +#define VNAME "Metamod" +#define VAUTHOR "Will Day " +#define VURL "http://www.metamod.org/" + +#define COPYRIGHT_YEAR "2006" + +// Various strings for the Windows DLL Resources in res_meta.rc +#define RC_COMMENTS "Metamod allows running multiple mod-like plugin DLLs, to add functionality or change the behavior of the running HLDS game mod. See " VURL +#define RC_DESC "Metamod Half-Life MOD DLL" +#define RC_FILENAME "METAMOD.DLL" +#define RC_INTERNAL "METAMOD" +#define RC_COPYRIGHT "Copyright© 2001-" COPYRIGHT_YEAR " Will Day; GPL licensed" +#define RC_LICENSE "Licensed under the GNU General Public License" + +#endif /* INFO_NAME_H */ diff --git a/sdk/metamod/linkent.h b/sdk/metamod/linkent.h new file mode 100644 index 0000000..6e17f44 --- /dev/null +++ b/sdk/metamod/linkent.h @@ -0,0 +1,117 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// linkent.h - export entities from mod "games" back to the HL engine + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef LINK_ENT_H +#define LINK_ENT_H + +#include // always + +#include "osdep.h" // DLLEXPORT, etc +#include "metamod.h" // GameDLL, etc +#include "mlist.h" // MPluginList::find_match, etc +#include "mplugin.h" // MPlugin::info, etc +#include "log_meta.h" // META_DEBUG, etc + +// Comments from SDK dlls/util.h: +//! This is the glue that hooks .MAP entity class names to our CPP classes. +//! The _declspec forces them to be exported by name so we can do a lookup with GetProcAddress(). +//! The function is used to intialize / allocate the object for the entity. + +// Adapted from LINK_ENTITY_TO_FUNC in adminmod linkfunc.cpp. + +typedef void (*ENTITY_FN) (entvars_t *); + +// Function to perform common code of LINK_ENTITY_TO_GAME. +void do_link_ent(ENTITY_FN *pfnEntity, int *missing, char *entStr, + entvars_t *pev); + +#define LINK_ENTITY_TO_GAME(entityName) \ + C_DLLEXPORT void entityName(entvars_t *pev); \ + void entityName(entvars_t *pev) { \ + static ENTITY_FN pfnEntity = NULL; \ + static int missing=0; \ + char *entStr; \ + entStr = STRINGIZE(entityName, 0); \ + do_link_ent(&pfnEntity, &missing, entStr, pev); \ + } + +// For now, we have to explicitly export functions for plugin entities, +// just as for gamedll entities. Ideally, this could be generalized in +// some manner, so that plugins can declare and use their own entities +// without having them explicitly supported by metamod, but I don't know +// yet if that is actually possible. +// +// LINK_ENTITY_TO_PLUGIN +// - if plugin not loaded & running, return +// - plugin has to be set loadable=startup only, else log error, return +// - (plugin loaded) if func missing, return +// - (plugin loaded) if func not found, dlsym +// - (plugin loaded) if func still not found, set missing, return +// - (plugin loaded, func found) call func +#define LINK_ENTITY_TO_PLUGIN(entityName, pluginName) \ + C_DLLEXPORT void entityName(entvars_t *pev); \ + void entityName(entvars_t *pev) { \ + static ENTITY_FN pfnEntity = NULL; \ + static int missing=0; \ + char *entStr; \ + MPlugin *findp; \ + entStr = STRINGIZE(entityName, 0); \ + if(missing) \ + return; \ + if(!pfnEntity) { \ + if(!(findp=Plugins->find_match(pluginName))) { \ + META_ERROR("Couldn't find loaded plugin '%s' for plugin entity '%s'", pluginName, entStr); \ + missing=1; \ + return; \ + } \ + if(findp->info && findp->info->loadable != PT_STARTUP) { \ + META_ERROR("Can't link entity '%s' for plugin '%s'; loadable != startup: %s", entStr, pluginName, findp->str_loadable()); \ + missing=1; \ + return; \ + } \ + META_DEBUG(9, ("Looking up plugin entity '%s'", entStr)); \ + pfnEntity = (ENTITY_FN) DLSYM(findp->handle, entStr); \ + } \ + if(!pfnEntity) { \ + META_ERROR("Couldn't find plugin entity '%s' in plugin DLL '%s'", entStr, findp->file); \ + missing=1; \ + return; \ + } \ + META_DEBUG(8, ("Linking plugin entity '%s'", entStr)); \ + (*pfnEntity)(pev); \ + } + +#endif /* LINK_ENT_H */ diff --git a/sdk/metamod/log_meta.h b/sdk/metamod/log_meta.h new file mode 100644 index 0000000..d2254ca --- /dev/null +++ b/sdk/metamod/log_meta.h @@ -0,0 +1,102 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// log_meta.h - functions & macros for logging + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef LOG_META_H +#define LOG_META_H + +#include "enginecallbacks.h" // ALERT, etc +#include "sdk_util.h" // UTIL_VarArgs, etc + +// Debug logging. +// +// This is done as a macro, rather than a function. This way, you can add +// DEBUG statements all over, without worrying about performance +// implications. If the debugging level is set low, all those statements +// will only generate a simple float/int compare each; if we were to use a +// function instead of a macro, it would end up wasting a lot of cpu cycles +// calling/returning from the function every time. With a fair number of +// DEBUG statements, or if they're placed in frequently excuted code, the +// overhead of the wasted function calls could significantly impact server +// performance. +// +// For this reason, we also compare directly to the float value of the +// cvar, rather than calling CVAR_GET_FLOAT() and thus generating a string +// compare for each DEBUG statement. +// +// Called as: +// META_DEBUG(3, ("return code: %d", ret)); +// +// Note the double parens, and the missing parens around "args" in the +// macro itself. Note also the "do..while(0)" loop wrapping the +// statements, so they become a single statement when expanded, necessary +// for times when it might be called as a single-statement result of an +// else (or other flow control). +// +// As suggested by Jussi Kivilinna: Use "if(meta_debug.value < level); else +// DO(something);" style because "meta_debug.value < level" is in most common +// case "false". Check disasm, contitional jumps are predicted not to be +// taken by CPU. +// +// Yes, it's all a bit of a hack. + +#define META_DEBUG(level, args) \ + do { if(meta_debug.value < level) break; else ALERT(at_logged, "[META] (debug:%d) %s\n", level, UTIL_VarArgs args ); } while(0) + +// max buffer size for printed messages +#define MAX_LOGMSG_LEN 1024 + +// max buffer size for client messages +#define MAX_CLIENTMSG_LEN 128 + +extern cvar_t meta_debug; + +// META_DEV provides debug logging via the cvar "developer" (when set to 1) +// and uses a function call rather than a macro as it's really intended to +// be used only during startup, before meta_debug has been set from reading +// server.cfg. +// NOTE: META_DEV has now been mostly obsoleted in the code. + +void META_CONS(const char *fmt, ...); +void META_DEV(const char *fmt, ...); +void META_INFO(const char *fmt, ...); +void META_WARNING(const char *fmt, ...); +void META_ERROR(const char *fmt, ...); +void META_LOG(const char *fmt, ...); +void META_CLIENT(edict_t *pEntity, const char *fmt, ...); + +void flush_ALERT_buffer(void); + +#endif /* LOG_META_H */ diff --git a/sdk/metamod/meta_api.h b/sdk/metamod/meta_api.h new file mode 100644 index 0000000..c76b129 --- /dev/null +++ b/sdk/metamod/meta_api.h @@ -0,0 +1,237 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// meta_api.h - description of metamod's DLL interface + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef META_API_H +#define META_API_H + +#include "dllapi.h" // GETENTITYAPI_FN, etc +#include "engine_api.h" // GET_ENGINE_FUNCTIONS_FN, etc +#include "plinfo.h" // plugin_info_t, etc +#include "mutil.h" // mutil_funcs_t, etc +#include "osdep.h" // DLLEXPORT, etc + +// Version consists of "major:minor", two separate integer numbers. +// Version 1 original +// Version 2 added plugin_info_t **pinfo +// Version 3 init split into query and attach, added detach +// Version 4 added (PLUG_LOADTIME now) to attach +// Version 5 changed mm ifvers int* to string, moved pl ifvers to info +// Version 5:1 added link support for entity "adminmod_timer" (adminmod) +// Version 5:2 added gamedll_funcs to meta_attach() [v1.0-rc2] +// Version 5:3 added mutil_funcs to meta_query() [v1.05] +// Version 5:4 added centersay utility functions [v1.06] +// Version 5:5 added Meta_Init to plugin API [v1.08] +// Version 5:6 added CallGameEntity utility function [v1.09] +// Version 5:7 added GetUserMsgID, GetUserMsgName util funcs [v1.11] +// Version 5:8 added GetPluginPath [v1.11] +// Version 5:9 added GetGameInfo [v1.14] +// Version 5:10 added GINFO_REALDLL_FULLPATH for GetGameInfo [v1.17] +// Version 5:11 added plugin loading and unloading API [v1.18] +// Version 5:12 added util code for checking player query status [v1.18] +// Version 5:13 added cvarquery2 support and api for calling hook tables [v1.19] +#define META_INTERFACE_VERSION "5:13" + +#ifdef UNFINISHED +// Version 5:99 added event hook utility functions [v.???] +#define META_INTERFACE_VERSION "5:99" +#endif /* UNFINISHED */ + +// Flags returned by a plugin's api function. +// NOTE: order is crucial, as greater/less comparisons are made. +typedef enum { + MRES_UNSET = 0, + MRES_IGNORED, // plugin didn't take any action + MRES_HANDLED, // plugin did something, but real function should still be called + MRES_OVERRIDE, // call real function, but use my return value + MRES_SUPERCEDE, // skip real function; use my return value +} META_RES; + +// Variables provided to plugins. +typedef struct meta_globals_s { + META_RES mres; // writable; plugin's return flag + META_RES prev_mres; // readable; return flag of the previous plugin called + META_RES status; // readable; "highest" return flag so far + void *orig_ret; // readable; return value from "real" function + void *override_ret; // readable; return value from overriding/superceding plugin +} meta_globals_t; + +extern meta_globals_t *gpMetaGlobals; +#define SET_META_RESULT(result) gpMetaGlobals->mres=result +#define RETURN_META(result) \ + do { gpMetaGlobals->mres=result; return; } while(0) +#define RETURN_META_VALUE(result, value) \ + do { gpMetaGlobals->mres=result; return(value); } while(0) +#define META_RESULT_STATUS gpMetaGlobals->status +#define META_RESULT_PREVIOUS gpMetaGlobals->prev_mres +#define META_RESULT_ORIG_RET(type) *(type *)gpMetaGlobals->orig_ret +#define META_RESULT_OVERRIDE_RET(type) *(type *)gpMetaGlobals->override_ret + +// Table of getapi functions, retrieved from each plugin. +typedef struct { + GETENTITYAPI_FN pfnGetEntityAPI; + GETENTITYAPI_FN pfnGetEntityAPI_Post; + GETENTITYAPI2_FN pfnGetEntityAPI2; + GETENTITYAPI2_FN pfnGetEntityAPI2_Post; + GETNEWDLLFUNCTIONS_FN pfnGetNewDLLFunctions; + GETNEWDLLFUNCTIONS_FN pfnGetNewDLLFunctions_Post; + GET_ENGINE_FUNCTIONS_FN pfnGetEngineFunctions; + GET_ENGINE_FUNCTIONS_FN pfnGetEngineFunctions_Post; +} META_FUNCTIONS; + +// Pair of function tables provided by game DLL. +typedef struct { + DLL_FUNCTIONS *dllapi_table; + NEW_DLL_FUNCTIONS *newapi_table; +} gamedll_funcs_t; + +// Declared in plugin; referenced in macros. +extern gamedll_funcs_t *gpGamedllFuncs; +extern mutil_funcs_t *gpMetaUtilFuncs; + +// Tell the dll that we'll be loading it as a metamod plugin, in case it +// needs to do something special prior to the standard query/attach +// procedure. In particular, this will allow for DLL's that can be used as +// both standalone DLL's and metamod plugins. (optional; not required in +// plugin) +C_DLLEXPORT void Meta_Init(void); +typedef void (*META_INIT_FN) (void); + +// Get info about plugin, compare meta_interface versions, provide meta +// utility callback functions. +C_DLLEXPORT int Meta_Query(char *interfaceVersion, + plugin_info_t **plinfo, + mutil_funcs_t *pMetaUtilFuncs); +typedef int (*META_QUERY_FN) (char *interfaceVersion, + plugin_info_t **plinfo, + mutil_funcs_t *pMetaUtilFuncs); + +// Attach the plugin to the API; get the table of getapi functions; give +// meta_globals and gamedll_funcs. +C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, + META_FUNCTIONS *pFunctionTable, + meta_globals_t *pMGlobals, + gamedll_funcs_t *pGamedllFuncs); +typedef int (*META_ATTACH_FN) (PLUG_LOADTIME now, + META_FUNCTIONS *pFunctionTable, + meta_globals_t *pMGlobals, + gamedll_funcs_t *pGamedllFuncs); + +// Detach the plugin; tell why and when. +C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); +typedef int (*META_DETACH_FN) (PLUG_LOADTIME now, PL_UNLOAD_REASON reason); + +// Standard HL SDK interface function prototypes. +C_DLLEXPORT int GetEntityAPI_Post(DLL_FUNCTIONS *pFunctionTable, + int interfaceVersion ); +C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, + int *interfaceVersion ); + +// Additional SDK-like interface function prototypes. +C_DLLEXPORT int GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, + int *interfaceVersion ); +C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, + int *interfaceVersion); +C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, + int *interfaceVersion); + +// Convenience macros for accessing GameDLL functions. Note: these talk +// _directly_ to the gamedll, and are not multiplexed through Metamod to +// the other plugins. + +// DLL API functions: +#define MDLL_FUNC gpGamedllFuncs->dllapi_table + +#define MDLL_GameDLLInit MDLL_FUNC->pfnGameInit +#define MDLL_Spawn MDLL_FUNC->pfnSpawn +#define MDLL_Think MDLL_FUNC->pfnThink +#define MDLL_Use MDLL_FUNC->pfnUse +#define MDLL_Touch MDLL_FUNC->pfnTouch +#define MDLL_Blocked MDLL_FUNC->pfnBlocked +#define MDLL_KeyValue MDLL_FUNC->pfnKeyValue +#define MDLL_Save MDLL_FUNC->pfnSave +#define MDLL_Restore MDLL_FUNC->pfnRestore +#define MDLL_ObjectCollsionBox MDLL_FUNC->pfnAbsBox +#define MDLL_SaveWriteFields MDLL_FUNC->pfnSaveWriteFields +#define MDLL_SaveReadFields MDLL_FUNC->pfnSaveReadFields +#define MDLL_SaveGlobalState MDLL_FUNC->pfnSaveGlobalState +#define MDLL_RestoreGlobalState MDLL_FUNC->pfnRestoreGlobalState +#define MDLL_ResetGlobalState MDLL_FUNC->pfnResetGlobalState +#define MDLL_ClientConnect MDLL_FUNC->pfnClientConnect +#define MDLL_ClientDisconnect MDLL_FUNC->pfnClientDisconnect +#define MDLL_ClientKill MDLL_FUNC->pfnClientKill +#define MDLL_ClientPutInServer MDLL_FUNC->pfnClientPutInServer +#define MDLL_ClientCommand MDLL_FUNC->pfnClientCommand +#define MDLL_ClientUserInfoChanged MDLL_FUNC->pfnClientUserInfoChanged +#define MDLL_ServerActivate MDLL_FUNC->pfnServerActivate +#define MDLL_ServerDeactivate MDLL_FUNC->pfnServerDeactivate +#define MDLL_PlayerPreThink MDLL_FUNC->pfnPlayerPreThink +#define MDLL_PlayerPostThink MDLL_FUNC->pfnPlayerPostThink +#define MDLL_StartFrame MDLL_FUNC->pfnStartFrame +#define MDLL_ParmsNewLevel MDLL_FUNC->pfnParmsNewLevel +#define MDLL_ParmsChangeLevel MDLL_FUNC->pfnParmsChangeLevel +#define MDLL_GetGameDescription MDLL_FUNC->pfnGetGameDescription +#define MDLL_PlayerCustomization MDLL_FUNC->pfnPlayerCustomization +#define MDLL_SpectatorConnect MDLL_FUNC->pfnSpectatorConnect +#define MDLL_SpectatorDisconnect MDLL_FUNC->pfnSpectatorDisconnect +#define MDLL_SpectatorThink MDLL_FUNC->pfnSpectatorThink +#define MDLL_Sys_Error MDLL_FUNC->pfnSys_Error +#define MDLL_PM_Move MDLL_FUNC->pfnPM_Move +#define MDLL_PM_Init MDLL_FUNC->pfnPM_Init +#define MDLL_PM_FindTextureType MDLL_FUNC->pfnPM_FindTextureType +#define MDLL_SetupVisibility MDLL_FUNC->pfnSetupVisibility +#define MDLL_UpdateClientData MDLL_FUNC->pfnUpdateClientData +#define MDLL_AddToFullPack MDLL_FUNC->pfnAddToFullPack +#define MDLL_CreateBaseline MDLL_FUNC->pfnCreateBaseline +#define MDLL_RegisterEncoders MDLL_FUNC->pfnRegisterEncoders +#define MDLL_GetWeaponData MDLL_FUNC->pfnGetWeaponData +#define MDLL_CmdStart MDLL_FUNC->pfnCmdStart +#define MDLL_CmdEnd MDLL_FUNC->pfnCmdEnd +#define MDLL_ConnectionlessPacket MDLL_FUNC->pfnConnectionlessPacket +#define MDLL_GetHullBounds MDLL_FUNC->pfnGetHullBounds +#define MDLL_CreateInstancedBaselines MDLL_FUNC->pfnCreateInstancedBaselines +#define MDLL_InconsistentFile MDLL_FUNC->pfnInconsistentFile +#define MDLL_AllowLagCompensation MDLL_FUNC->pfnAllowLagCompensation + +// NEW API functions: +#define MNEW_FUNC gpGamedllFuncs->newapi_table + +#define MNEW_OnFreeEntPrivateData MNEW_FUNC->pfnOnFreeEntPrivateData +#define MNEW_GameShutdown MNEW_FUNC->pfnGameShutdown +#define MNEW_ShouldCollide MNEW_FUNC->pfnShouldCollide +#define MNEW_CvarValue MNEW_FUNC->pfnCvarValue +#define MNEW_CvarValue2 MNEW_FUNC->pfnCvarValue2 + +#endif /* META_API_H */ diff --git a/sdk/metamod/meta_eiface.h b/sdk/metamod/meta_eiface.h new file mode 100644 index 0000000..4b804a6 --- /dev/null +++ b/sdk/metamod/meta_eiface.h @@ -0,0 +1,478 @@ + +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// meta_eiface.h - wrapper for engine/dll interface + +/* + * Copyright (c) 2001-2006 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MM_META_EIFACE_H +#define MM_META_EIFACE_H + +#include // NEW_DLL_FUNCTIONS, enginefuncs_t +#include // memset() + + +// We use our own versions of the engine/dll interface structs. We add a +// few dummy entries to the end and set them to 0. That way we are +// protected from updates to the HL SDK adding new functions which would +// cause a) the game dll copying arbitrary values from us and b) the game +// dll overwriting our memory when using an old Metamod with a new game +// dll. + +const int c_NumDummies = 5; +typedef void (*pdummyfunc)(void); + + +// -------------------------------------------------------------------- +// meta_new_dll_functions_t +// -------------------------------------------------------------------- + +struct meta_new_dll_functions_t : public NEW_DLL_FUNCTIONS { + // Array of five dummy function pointers. Must be filled with NULL. + pdummyfunc dummies[c_NumDummies]; + + // functions : + + meta_new_dll_functions_t(); + meta_new_dll_functions_t( + void (*pfnOnFreeEntPrivateData) (edict_t*), + void (*pfnGameShutdown) (void), + int (*pfnShouldCollide) (edict_t*, edict_t*), + void (*pfnCvarValue) (const edict_t*, const char*), + void (*pfnCvarValue2) (const edict_t*, int, const char*, const char*) + ); + + meta_new_dll_functions_t( const meta_new_dll_functions_t& ); + meta_new_dll_functions_t& operator=( const meta_new_dll_functions_t& ); + + // Fill this object with pointers copied from a NEW_DLL_FUNCTIONS struct. + void set_from( NEW_DLL_FUNCTIONS* pFuncs ); + + // Copy the pointers from this object to a NEW_DLL_FUNCTIONS struct. + void copy_to( NEW_DLL_FUNCTIONS* pFuncs ); + + // return the engine's version of NEW_DLL_FUNCTIONS + int version( void ); + + + private: + + // data : + + // The NEW_DLL_FUNCTIONS struct also changed, but the version + // number did not change. That begs the question why to have + // it versioned in the first place, but whaddaya know. + // While the official version is left at 1, we internally + // calculate a different version of the engine's NEW_DLL_FUNCTIONS + // struct since we know that the engine lies to us about the + // version that it uses. + // + // The default version is 1. + // + // With the enginefuncs interface version 156 the function + // pfnCvarValue() was added, which we call version 2. + // + // With the enginefuncs interface version 157 the function + // pfnCvarValue2() was added, which we call version 3. + // + // If Valve ever decides to change the version of the + // NEW_DLL_FUNCTIONS interface in the future (haha), + // we are in trouble and will need to change our + // internal versions. + + static int sm_version; + + // functions : + + // Calculates our idea of the engine's version of the + // NEW_DLL_FUNCTIONS interface. Stores this version for future + // reference in m_version and returns it. + int determine_interface_version( void ); + + // Comfort function to determine the size of the NEW_DLL_FUNCTIONS + // struct for the different versions. + // If passed a version number other than 0, the size for that + // specific version is returned. + // If passed 0 as version number (default) the size for the version + // that was determined to be the version of the currently connected + // engine's interface. Should that version have not yet been + // determined (via the enginefuncs_t interface), 0 is returned to + // indicated this error state. + size_t get_size( int version = 0 ); +}; + + +// Inline functions + +inline meta_new_dll_functions_t::meta_new_dll_functions_t() +{ + memset( this, 0, sizeof(meta_new_dll_functions_t) ); +} + + +inline meta_new_dll_functions_t::meta_new_dll_functions_t( const meta_new_dll_functions_t& _rhs ) +{ + memcpy( this, &_rhs, sizeof(NEW_DLL_FUNCTIONS) ); + memset( dummies, 0, sizeof(pdummyfunc) * c_NumDummies ); +} + + +inline meta_new_dll_functions_t& meta_new_dll_functions_t::operator=( const meta_new_dll_functions_t& _rhs) +{ + memcpy( this, &_rhs, sizeof(NEW_DLL_FUNCTIONS) ); + return *this; +} + + +inline void meta_new_dll_functions_t::set_from( NEW_DLL_FUNCTIONS* _pFuncs ) +{ + memcpy( this, _pFuncs, sizeof(NEW_DLL_FUNCTIONS) ); +} + + +inline int meta_new_dll_functions_t::version( void ) +{ + return sm_version ? sm_version : determine_interface_version(); +} + + + +// No meta version of DLL_FUNCTIONS because that won't be changing anymore. + + + +// -------------------------------------------------------------------- +// meta_enginefuncs_t +// -------------------------------------------------------------------- + + +struct meta_enginefuncs_t : public enginefuncs_t { + // data : + + // Array of five dummy function pointers. Must be filled with NULL. + pdummyfunc dummies[c_NumDummies]; + + // functions : + + meta_enginefuncs_t(); + + // Spawn of the devil + meta_enginefuncs_t( + int (*_pfnPrecacheModel) (char*), + int (*_pfnPrecacheSound) (char*), + void (*_pfnSetModel) (edict_t*, const char*), + int (*_pfnModelIndex) (const char*), + int (*_pfnModelFrames) (int), + void (*_pfnSetSize) (edict_t*, const float*, const float*), + void (*_pfnChangeLevel) (char*, char*), + void (*_pfnGetSpawnParms) (edict_t*), + void (*_pfnSaveSpawnParms) (edict_t*), + float (*_pfnVecToYaw) (const float*), + void (*_pfnVecToAngles) (const float*, float*), + void (*_pfnMoveToOrigin) (edict_t*, const float*, float, int), + void (*_pfnChangeYaw) (edict_t*), + void (*_pfnChangePitch) (edict_t*), + edict_t* (*_pfnFindEntityByString) (edict_t*, const char*, const char*), + int (*_pfnGetEntityIllum) (edict_t*), + edict_t* (*_pfnFindEntityInSphere) (edict_t*, const float*, float), + edict_t* (*_pfnFindClientInPVS) (edict_t*), + edict_t* (*_pfnEntitiesInPVS) (edict_t*), + void (*_pfnMakeVectors) (const float*), + void (*_pfnAngleVectors) (const float*, float*, float*, float*), + edict_t* (*_pfnCreateEntity) (void), + void (*_pfnRemoveEntity) (edict_t*), + edict_t* (*_pfnCreateNamedEntity) (int), + void (*_pfnMakeStatic) (edict_t*), + int (*_pfnEntIsOnFloor) (edict_t*), + int (*_pfnDropToFloor) (edict_t*), + int (*_pfnWalkMove) (edict_t*, float, float, int), + void (*_pfnSetOrigin) (edict_t*, const float*), + void (*_pfnEmitSound) (edict_t*, int, const char*, float, float, int, int), + void (*_pfnEmitAmbientSound) (edict_t*, float*, const char*, float, float, int, int), + void (*_pfnTraceLine) (const float*, const float*, int, edict_t*, TraceResult*), + void (*_pfnTraceToss) (edict_t*, edict_t*, TraceResult*), + int (*_pfnTraceMonsterHull) (edict_t*, const float*, const float*, int, edict_t*, TraceResult*), + void (*_pfnTraceHull) (const float*, const float*, int, int, edict_t*, TraceResult*), + void (*_pfnTraceModel) (const float*, const float*, int, edict_t*, TraceResult*), + const char* (*_pfnTraceTexture) (edict_t*, const float*, const float*), + void (*_pfnTraceSphere) (const float*, const float*, int, float, edict_t*, TraceResult*), + void (*_pfnGetAimVector) (edict_t*, float, float*), + void (*_pfnServerCommand) (char*), + void (*_pfnServerExecute) (void), + void (*_pfnClientCommand) (edict_t*, char*, ...), + void (*_pfnParticleEffect) (const float*, const float*, float, float), + void (*_pfnLightStyle) (int, char*), + int (*_pfnDecalIndex) (const char*), + int (*_pfnPointContents) (const float*), + void (*_pfnMessageBegin) (int, int, const float*, edict_t*), + void (*_pfnMessageEnd) (void), + void (*_pfnWriteByte) (int), + void (*_pfnWriteChar) (int), + void (*_pfnWriteShort) (int), + void (*_pfnWriteLong) (int), + void (*_pfnWriteAngle) (float), + void (*_pfnWriteCoord) (float), + void (*_pfnWriteString) (const char*), + void (*_pfnWriteEntity) (int), + void (*_pfnCVarRegister) (cvar_t*), + float (*_pfnCVarGetFloat) (const char*), + const char* (*_pfnCVarGetString) (const char*), + void (*_pfnCVarSetFloat) (const char*, float), + void (*_pfnCVarSetString) (const char*, const char*), + void (*_pfnAlertMessage) (ALERT_TYPE, char*, ...), + void (*_pfnEngineFprintf) (void*, char*, ...), + void* (*_pfnPvAllocEntPrivateData) (edict_t*, int32), + void* (*_pfnPvEntPrivateData) (edict_t*), + void (*_pfnFreeEntPrivateData) (edict_t*), + const char* (*_pfnSzFromIndex) (int), + int (*_pfnAllocString) (const char*), + struct entvars_s*(*_pfnGetVarsOfEnt) (edict_t*), + edict_t* (*_pfnPEntityOfEntOffset) (int), + int (*_pfnEntOffsetOfPEntity) (const edict_t*), + int (*_pfnIndexOfEdict) (const edict_t*), + edict_t* (*_pfnPEntityOfEntIndex) (int), + edict_t* (*_pfnFindEntityByVars) (struct entvars_s*), + void* (*_pfnGetModelPtr) (edict_t*), + int (*_pfnRegUserMsg) (const char*, int), + void (*_pfnAnimationAutomove) (const edict_t*, float), + void (*_pfnGetBonePosition) (const edict_t*, int, float*, float* ), + uint32 (*_pfnFunctionFromName) (const char*), + const char* (*_pfnNameForFunction) (uint32), + void (*_pfnClientPrintf) (edict_t*, PRINT_TYPE, const char*), + void (*_pfnServerPrint) (const char*), + const char* (*_pfnCmd_Args) (void), + const char* (*_pfnCmd_Argv) (int argc), + int (*_pfnCmd_Argc) (void), + void (*_pfnGetAttachment) (const edict_t*, int, float*, float*), + void (*_pfnCRC32_Init) (CRC32_t*), + void (*_pfnCRC32_ProcessBuffer) (CRC32_t*, void*, int), + void (*_pfnCRC32_ProcessByte) (CRC32_t*, unsigned char), + CRC32_t (*_pfnCRC32_Final) (CRC32_t), + int32 (*_pfnRandomLong) (int32, int32), + float (*_pfnRandomFloat) (float, float), + void (*_pfnSetView) (const edict_t*, const edict_t*), + float (*_pfnTime) (void), + void (*_pfnCrosshairAngle) (const edict_t*, float, float), + byte* (*_pfnLoadFileForMe) (char*, int*), + void (*_pfnFreeFile) (void*), + void (*_pfnEndSection) (const char*), + int (*_pfnCompareFileTime) (char*, char*, int*), + void (*_pfnGetGameDir) (char*), + void (*_pfnCvar_RegisterVariable) (cvar_t*), + void (*_pfnFadeClientVolume) (const edict_t*, int, int, int, int), + void (*_pfnSetClientMaxspeed) (const edict_t*, float), + edict_t* (*_pfnCreateFakeClient) (const char*), + void (*_pfnRunPlayerMove) (edict_t*, const float*, float, float, float, unsigned short, byte, byte), + int (*_pfnNumberOfEntities) (void), + char* (*_pfnGetInfoKeyBuffer) (edict_t*), + char* (*_pfnInfoKeyValue) (char*, char*), + void (*_pfnSetKeyValue) (char*, char*, char*), + void (*_pfnSetClientKeyValue) (int, char*, char*, char*), + int (*_pfnIsMapValid) (char*), + void (*_pfnStaticDecal) (const float*, int, int, int), + int (*_pfnPrecacheGeneric) (char*), + int (*_pfnGetPlayerUserId) (edict_t*), + void (*_pfnBuildSoundMsg) (edict_t*, int, const char*, float, float, int, int, int, int, const float*, edict_t*), + int (*_pfnIsDedicatedServer) (void), + cvar_t* (*_pfnCVarGetPointer) (const char*), + unsigned int (*_pfnGetPlayerWONId) (edict_t*), + void (*_pfnInfo_RemoveKey) (char*, const char*), + const char* (*_pfnGetPhysicsKeyValue) (const edict_t*, const char*), + void (*_pfnSetPhysicsKeyValue) (const edict_t*, const char*, const char*), + const char* (*_pfnGetPhysicsInfoString) (const edict_t*), + unsigned short (*_pfnPrecacheEvent) (int, const char*), + void (*_pfnPlaybackEvent) (int, const edict_t*, unsigned short, float, float*, float*, float, float, int, int, int, int), + unsigned char* (*_pfnSetFatPVS) (float*), + unsigned char* (*_pfnSetFatPAS) (float*), + int (*_pfnCheckVisibility) (const edict_t*, unsigned char*), + void (*_pfnDeltaSetField) (struct delta_s*, const char*), + void (*_pfnDeltaUnsetField) (struct delta_s*, const char*), + void (*_pfnDeltaAddEncoder) (char*, void (*)(struct delta_s*, const unsigned char*, const unsigned char*)), + int (*_pfnGetCurrentPlayer) (void), + int (*_pfnCanSkipPlayer) (const edict_t*), + int (*_pfnDeltaFindField) (struct delta_s*, const char*), + void (*_pfnDeltaSetFieldByIndex) (struct delta_s*, int), + void (*_pfnDeltaUnsetFieldByIndex) (struct delta_s*, int), + void (*_pfnSetGroupMask) (int, int), + int (*_pfnCreateInstancedBaseline) (int, struct entity_state_s*), + void (*_pfnCvar_DirectSet) (struct cvar_s*, char*), + void (*_pfnForceUnmodified) (FORCE_TYPE, float*, float*, const char*), + void (*_pfnGetPlayerStats) (const edict_t*, int*, int*), + void (*_pfnAddServerCommand) (char*, void (*) (void)), + qboolean (*_pfnVoice_GetClientListening) (int, int), + qboolean (*_pfnVoice_SetClientListening) (int, int, qboolean), + const char* (*_pfnGetPlayerAuthId) (edict_t*), + sequenceEntry_s* (*_pfnSequenceGet) (const char*, const char*), + sentenceEntry_s* (*_pfnSequencePickSentence) (const char*, int, int*), + int (*_pfnGetFileSize) (char*), + unsigned int (*_pfnGetApproxWavePlayLen) (const char*), + int (*_pfnIsCareerMatch) (void), + int (*_pfnGetLocalizedStringLength) (const char*), + void (*_pfnRegisterTutorMessageShown) (int), + int (*_pfnGetTimesTutorMessageShown) (int), + void (*_pfnProcessTutorMessageDecayBuffer) (int*, int), + void (*_pfnConstructTutorMessageDecayBuffer)(int*, int), + void (*_pfnResetTutorMessageDecayData) (void), + void (*_pfnQueryClientCvarValue) (const edict_t*, const char*), + void (*_pfnQueryClientCvarValue2) (const edict_t*, const char*, int) + ); + + meta_enginefuncs_t( const meta_enginefuncs_t& ); + meta_enginefuncs_t& operator=( const meta_enginefuncs_t& ); + + // Fill this object with pointers copied from an enginefuncs_t struct. + void set_from( enginefuncs_t *pFuncs ); + + // Copy the pointers from this object to an enginefuncs_t struct. + void copy_to( enginefuncs_t *pFuncs ); + + // return the engine interface version + static int version( void ); + + protected: + + // data : + + // The version of the engine functions interface. It is frozen at 138. But no one knows + // when that was and what it looked like then. So we simply interprete it as the + // number of functions that the enginefuncs struct contains. + // + // That means we get gaps inbetween versions and right now we can detect only + // about five different versions anyway, but that suffices for the current itches + // to get scratched. + // + // The default is hence 138. + // A value of 0 means "not yet determined". + // Other possible versions currently detectable: + // 144: engine versions after 1.1.0.9 build 1996 + // 147: engine versions after build 2384 with pfnGetFileSize() + // 155: all versions between build 2384 and the one + // including pfnQueryClientCvarValue() + // 156: includes pfnQueryClientCvarValue() + // 157: includes pfnQueryClientCvarValue2() + static int sm_version; + +}; + +// +// Inline functions +// + +inline meta_enginefuncs_t::meta_enginefuncs_t() +{ + memset( this, 0, sizeof(meta_enginefuncs_t) ); +} + + +inline meta_enginefuncs_t::meta_enginefuncs_t( const meta_enginefuncs_t& _rhs ) +{ + memcpy( this, &_rhs, sizeof(enginefuncs_t) ); + memset( dummies, 0, sizeof(pdummyfunc) * c_NumDummies ); +} + + +inline meta_enginefuncs_t& meta_enginefuncs_t::operator=( const meta_enginefuncs_t& _rhs) +{ + memcpy( this, &_rhs, sizeof(enginefuncs_t) ); + return *this; +} + + +inline void meta_enginefuncs_t::set_from( enginefuncs_t* _pFuncs ) +{ + memcpy( this, _pFuncs, sizeof(enginefuncs_t) ); +} + + +inline void meta_enginefuncs_t::copy_to( enginefuncs_t* _pFuncs ) +{ + memcpy( _pFuncs, this, sizeof(enginefuncs_t) ); +} + + +inline int meta_enginefuncs_t::version( void ) +{ + return sm_version; +} + + + +// -------------------------------------------------------------------- +// HL_enginefuncs_t +// -------------------------------------------------------------------- + +// +// This is a specialisation of the meta_enginefuncs_t struct which is only +// used for the initial copy of the engine functions, i.e. those we get +// passed from the HL engine right at the beginning. +// This specialisation does some extra initialisation when getting set up +// like calculating the engine interface version and fixing up any invalid +// pointers. +// Since there is only one master copy of engine functions this could be +// implemented as a singleton. This is left as an option for later. +// +struct HL_enginefuncs_t : public meta_enginefuncs_t { + + // functions : + + HL_enginefuncs_t() : meta_enginefuncs_t() { }; + + // Fill this object with pointers copied from an enginefuncs_t struct + // and fixup the interface. + // For this class this happens in the GiveFptrsToDll() function + // with the pointers passed from the HL engine. + void initialise_interface( enginefuncs_t *pFuncs ); + + + private: + + // functions : + + // Moving copy_to() and set_from() to the private space. + void set_from( enginefuncs_t *pFuncs ) { meta_enginefuncs_t::set_from( pFuncs ); }; + void copy_to( enginefuncs_t *pFuncs ) { meta_enginefuncs_t::copy_to( pFuncs ); }; + + + // Determine the version of the engine interface from the + // enginefuncs signature. + void determine_engine_interface_version( void ); + + // Fixup the enginefuncs pointers according to the determined + // version as some pointers may be invalid. + void fixup_engine_interface( void ); +}; + + + +#endif /* META_EIFACE_H */ + diff --git a/sdk/metamod/metamod.h b/sdk/metamod/metamod.h new file mode 100644 index 0000000..7c4a61f --- /dev/null +++ b/sdk/metamod/metamod.h @@ -0,0 +1,426 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// metamod.h - (main) description of metamod operations + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef METAMOD_H +#define METAMOD_H + +#include "meta_api.h" // META_RES, etc +#include "mlist.h" // MPluginList, etc +#include "mreg.h" // MRegCmdList, etc +#include "conf_meta.h" // MConfig +#include "osdep.h" // NAME_MAX, etc +#include "types_meta.h" // mBOOL +#include "mplayer.h" // MPlayerList +#include "meta_eiface.h" // HL_enginefuncs_t, meta_enginefuncs_t +#include "engine_t.h" // engine_t, Engine + +// file that lists plugins to load at startup +#define PLUGINS_INI "addons/metamod/plugins.ini" +#define OLD_PLUGINS_INI "metamod.ini" + +// file that contains commands to metamod plugins at startup +#define EXEC_CFG "addons/metamod/exec.cfg" +#define OLD_EXEC_CFG "metaexec.cfg" + +// previously, file that contained path for an override-gamedll +#define OLD_GAMEDLL_TXT "metagame.ini" + +// generic config file +#define CONFIG_INI "addons/metamod/config.ini" + + +// cvar to contain version +extern cvar_t meta_version; + +// Info about the game dll/mod. +typedef struct gamedll_s { + char name[NAME_MAX]; // ie "cstrike" (from gamedir) + char *desc; // ie "Counter-Strike" + char gamedir[PATH_MAX]; // ie "/home/willday/half-life/cstrike" + char pathname[PATH_MAX]; // ie "/home/willday/half-life/cstrike/dlls/cs_i386.so" + char const *file; // ie "cs_i386.so" + char real_pathname[PATH_MAX]; // in case pathname overridden by bot, etc + DLHANDLE handle; + gamedll_funcs_t funcs; // dllapi_table, newapi_table +} gamedll_t; +extern gamedll_t GameDLL; + +// SDK variables for storing engine funcs and globals. +extern HL_enginefuncs_t g_engfuncs; +extern globalvars_t *gpGlobals; + +// Our modified version of the engine funcs, to give to plugins. +extern meta_enginefuncs_t g_plugin_engfuncs; + +// Config structure. +extern MConfig *Config; + +// List of plugins loaded/opened/running. +extern MPluginList *Plugins; + +// List of command functions registered by plugins. +extern MRegCmdList *RegCmds; + +// List of cvar structures registered by plugins. +extern MRegCvarList *RegCvars; + +// List of user messages registered by gamedll. +extern MRegMsgList *RegMsgs; + +#ifdef UNFINISHED +// List of event/logline hooks requested by plugins. +extern MHookList *Hooks; +#endif /* UNFINISHED */ + +// Data provided to plugins. +// Separate copies to prevent plugins from modifying "readable" parts. +// See meta_api.h for meta_globals_t structure. +extern meta_globals_t PublicMetaGlobals; +extern meta_globals_t PrivateMetaGlobals; + +// hook function tables +extern DLL_FUNCTIONS *pHookedDllFunctions; +extern NEW_DLL_FUNCTIONS *pHookedNewDllFunctions; + +// (patch by hullu) +// Safety check for metamod-bot-plugin bugfix. +// engine_api->pfnRunPlayerMove calls dllapi-functions before it returns. +// This causes problems with bots running as metamod plugins, because +// metamod assumed that PublicMetaGlobals is free to be used. +// With call_count we can fix this by backuping up PublicMetaGlobals if +// it's already being used. +extern unsigned int CALL_API_count; + +// stores previous requestid counter +extern int requestid_counter; + +// (patch by BAILOPAN) +// Holds cached player info, right now only things for querying cvars +// Max players is always 32, small enough that we can use a static array +extern MPlayerList g_Players; + +void metamod_startup(void); + +mBOOL meta_init_gamedll(void); +mBOOL meta_load_gamedll(void); + +// ===== lotsa macros... ====================================================== + +// These are the meat of the metamod processing, and are as ugly as (or +// uglier) than they look. This is done via macros, because of the varying +// parameter types (int, void, edict_t*, etc) as well as varying +// function-pointer types and different api tables (dllapi, newapi, +// engine), which just can't be passed to a function. And, since the +// operation is similar for each api call, I didn't want to keep +// duplicating code all over the place. Thus the ugly macros. +// +// The basic operation is, for each api call: +// - iterate through list of plugins +// - for each plugin, if it provides this api call, then call the +// function in the plugin +// - call the "real" function (in the game dll, or from the engine) +// - for each plugin, check for a "post" version of the function, and call +// if present +// +// +// Also, for any api call, each plugin has the opportunity to replace the +// real routine, in two ways: +// - prevent the real routine from being called ("supercede") +// - allow the real routine to be called, but change the value that's +// returned ("override") +// +// Thus after each plugin is called, its META_RETURN flag is checked, and +// action taken appropriately. Note that supercede/override only affects +// the _real_ routine; other plugins will still be called. +// +// In addition to the SUPERCEDE and OVERRIDE flags, there are two +// additional flags a plugin can return: +// - HANDLED ("I did something here") +// - IGNORED ("I didn't really do anything") +// +// These aren't used by metamod itself, but could be used by plugins to +// get an idea if a previous plugin did anything. +// +// +// The 5 basic macros are: +// SETUP +// CALL_PLUGIN +// CALL_GAME and CALL_ENGINE +// RETURN +// +// These 5 are actually used to build second level macros for each api type +// (dllapi, newapi, engine), with the CALL_PLUGIN macro being used twice +// (before and after). Altogether, they end up expanding to approx 150 +// lines of code for _each_ api call. Ack, ugly indeed. +// +// However, due to some functions returning 'void', and others returning an +// actual value, I had to have separate macros for the two, since I +// couldn't seem to generalize the two into a form that the compiler would +// accept. Thus there are "_void" versions of the 5 macros; these are +// listed first. + +// ===== macros for void-returning functions ================================== + +// declare/init some variables +#define SETUP_API_CALLS_void(FN_TYPE, pfnName, api_info_table) \ + int i; \ + META_RES mres=MRES_UNSET, status=MRES_UNSET, prev_mres=MRES_UNSET; \ + MPlugin *iplug; \ + FN_TYPE pfn_routine=NULL; \ + int loglevel=api_info_table.pfnName.loglevel; \ + char *pfn_string=api_info_table.pfnName.name; \ + meta_globals_t backup_meta_globals; \ + /* fix bug with metamod-bot-plugins (hullu)*/ \ + if (CALL_API_count++>0) \ + /* backup publicmetaglobals */ \ + backup_meta_globals = PublicMetaGlobals; + +// call each plugin +#define CALL_PLUGIN_API_void(post, pfnName, pfn_args, api_table) \ + prev_mres=MRES_UNSET; \ + for(i=0; i < Plugins->endlist; i++) { \ + iplug=&Plugins->plist[i]; \ + if (iplug->status != PL_RUNNING) \ + continue; \ + if(iplug->api_table && (pfn_routine=iplug->api_table->pfnName)); \ + else \ + /* plugin doesn't provide this function */ \ + continue; \ + /* initialize PublicMetaGlobals */ \ + PublicMetaGlobals.mres = MRES_UNSET; \ + PublicMetaGlobals.prev_mres = prev_mres; \ + PublicMetaGlobals.status = status; \ + /* call plugin */ \ + META_DEBUG(loglevel, ("Calling %s:%s%s()", iplug->file, pfn_string, (post?"_Post":""))); \ + pfn_routine pfn_args; \ + /* plugin's result code */ \ + mres=PublicMetaGlobals.mres; \ + if(mres > status) \ + status = mres; \ + /* save this for successive plugins to see */ \ + prev_mres = mres; \ + if(mres==MRES_UNSET) \ + META_ERROR("Plugin didn't set meta_result: %s:%s%s()", iplug->file, pfn_string, (post?"_Post":"")); \ + if(post && mres==MRES_SUPERCEDE) \ + META_ERROR("MRES_SUPERCEDE not valid in Post functions: %s:%s%s()", iplug->file, pfn_string, (post?"_Post":"")); \ + } + +// call "real" function, from gamedll +#define CALL_GAME_API_void(pfnName, pfn_args, api_table) \ + CALL_API_count--; \ + if(status==MRES_SUPERCEDE) { \ + META_DEBUG(loglevel, ("Skipped (supercede) %s:%s()", GameDLL.file, pfn_string)); \ + /* don't return here; superceded game routine, but still allow \ + * _post routines to run. \ + */ \ + } \ + else if(GameDLL.funcs.api_table) { \ + pfn_routine=GameDLL.funcs.api_table->pfnName; \ + if(pfn_routine) { \ + META_DEBUG(loglevel, ("Calling %s:%s()", GameDLL.file, pfn_string)); \ + pfn_routine pfn_args; \ + } \ + /* don't complain for NULL routines in NEW_DLL_FUNCTIONS */ \ + else if((void*) GameDLL.funcs.api_table != (void*) GameDLL.funcs.newapi_table) { \ + META_ERROR("Couldn't find api call: %s:%s", GameDLL.file, pfn_string); \ + status=MRES_UNSET; \ + } \ + } \ + else { \ + META_DEBUG(loglevel, ("No api table defined for api call: %s:%s", GameDLL.file, pfn_string)); \ + } \ + CALL_API_count++; + +// call "real" function, from engine +#define CALL_ENGINE_API_void(pfnName, pfn_args) \ + CALL_API_count--; \ + if(status==MRES_SUPERCEDE) { \ + META_DEBUG(loglevel, ("Skipped (supercede) engine:%s()", pfn_string)); \ + /* don't return here; superceded game routine, but still allow \ + * _post routines to run. \ + */ \ + } \ + else { \ + pfn_routine=Engine.funcs->pfnName; \ + if(pfn_routine) { \ + META_DEBUG(loglevel, ("Calling engine:%s()", pfn_string)); \ + pfn_routine pfn_args; \ + } \ + else { \ + META_ERROR("Couldn't find api call: engine:%s", pfn_string); \ + status=MRES_UNSET; \ + } \ + } \ + CALL_API_count++; + +// return (void) +#define RETURN_API_void() \ + if (--CALL_API_count>0) \ + /*restore backup*/ \ + PublicMetaGlobals = backup_meta_globals; \ + return; + + +// ===== macros for type-returning functions ================================== + +// declare/init some variables +#define SETUP_API_CALLS(ret_t, ret_init, FN_TYPE, pfnName, api_info_table) \ + int i; \ + ret_t dllret=ret_init; \ + ret_t override_ret=ret_init; \ + ret_t pub_override_ret=ret_init; \ + ret_t orig_ret=ret_init; \ + ret_t pub_orig_ret=ret_init; \ + META_RES mres=MRES_UNSET, status=MRES_UNSET, prev_mres=MRES_UNSET; \ + MPlugin *iplug; \ + FN_TYPE pfn_routine=NULL; \ + int loglevel=api_info_table.pfnName.loglevel; \ + char *pfn_string=api_info_table.pfnName.name; \ + meta_globals_t backup_meta_globals; \ + /*Fix bug with metamod-bot-plugins*/ \ + if (CALL_API_count++>0) \ + /*Backup PublicMetaGlobals*/ \ + backup_meta_globals = PublicMetaGlobals; + +// call each plugin +#define CALL_PLUGIN_API(post, ret_init, pfnName, pfn_args, MRES_TYPE, api_table) \ + override_ret=ret_init; \ + prev_mres=MRES_UNSET; \ + for(i=0; i < Plugins->endlist; i++) { \ + if (Plugins->plist[i].status != PL_RUNNING) \ + continue; \ + iplug=&Plugins->plist[i]; \ + if(iplug->api_table && (pfn_routine=iplug->api_table->pfnName)); \ + else \ + /* plugin doesn't provide this function */ \ + continue; \ + /* initialize PublicMetaGlobals */ \ + PublicMetaGlobals.mres = MRES_UNSET; \ + PublicMetaGlobals.prev_mres = prev_mres; \ + PublicMetaGlobals.status = status; \ + pub_orig_ret = orig_ret; \ + PublicMetaGlobals.orig_ret = &pub_orig_ret; \ + if(status==MRES_TYPE) { \ + pub_override_ret = override_ret; \ + PublicMetaGlobals.override_ret = &pub_override_ret; \ + } \ + /* call plugin */ \ + META_DEBUG(loglevel, ("Calling %s:%s%s()", iplug->file, pfn_string, (post?"_Post":""))); \ + dllret=pfn_routine pfn_args; \ + /* plugin's result code */ \ + mres=PublicMetaGlobals.mres; \ + if(mres > status) \ + status = mres; \ + /* save this for successive plugins to see */ \ + prev_mres = mres; \ + if(mres==MRES_TYPE) \ + override_ret = pub_override_ret = dllret; \ + else if(mres==MRES_UNSET) \ + META_ERROR("Plugin didn't set meta_result: %s:%s%s()", iplug->file, pfn_string, (post?"_Post":"")); \ + else if(post && mres==MRES_SUPERCEDE) \ + META_ERROR("MRES_SUPERCEDE not valid in Post functions: %s:%s%s()", iplug->file, pfn_string, (post?"_Post":"")); \ + } + +// call "real" function, from gamedll +#define CALL_GAME_API(pfnName, pfn_args, api_table) \ + CALL_API_count--; \ + if(status==MRES_SUPERCEDE) { \ + META_DEBUG(loglevel, ("Skipped (supercede) %s:%s()", GameDLL.file, pfn_string)); \ + orig_ret = pub_orig_ret = override_ret; \ + PublicMetaGlobals.orig_ret = &pub_orig_ret; \ + /* don't return here; superceded game routine, but still allow \ + * _post routines to run. \ + */ \ + } \ + else if(GameDLL.funcs.api_table) { \ + pfn_routine=GameDLL.funcs.api_table->pfnName; \ + if(pfn_routine) { \ + META_DEBUG(loglevel, ("Calling %s:%s()", GameDLL.file, pfn_string)); \ + dllret=pfn_routine pfn_args; \ + orig_ret = dllret; \ + } \ + /* don't complain for NULL routines in NEW_DLL_FUNCTIONS */ \ + else if((void*) GameDLL.funcs.api_table != (void*) GameDLL.funcs.newapi_table) { \ + META_ERROR("Couldn't find api call: %s:%s", GameDLL.file, pfn_string); \ + status=MRES_UNSET; \ + } \ + } \ + else { \ + META_DEBUG(loglevel, ("No api table defined for api call: %s:%s", GameDLL.file, pfn_string)); \ + } \ + CALL_API_count++; + +// call "real" function, from engine +#define CALL_ENGINE_API(pfnName, pfn_args) \ + CALL_API_count--; \ + if(status==MRES_SUPERCEDE) { \ + META_DEBUG(loglevel, ("Skipped (supercede) engine:%s()", pfn_string)); \ + orig_ret = pub_orig_ret = override_ret; \ + PublicMetaGlobals.orig_ret = &pub_orig_ret; \ + /* don't return here; superceded game routine, but still allow \ + * _post routines to run. \ + */ \ + } \ + else { \ + pfn_routine=Engine.funcs->pfnName; \ + if(pfn_routine) { \ + META_DEBUG(loglevel, ("Calling engine:%s()", pfn_string)); \ + dllret=pfn_routine pfn_args; \ + orig_ret = dllret; \ + } \ + else { \ + META_ERROR("Couldn't find api call: engine:%s", pfn_string); \ + status=MRES_UNSET; \ + } \ + } \ + CALL_API_count++; + +// return a value +#define RETURN_API() \ + if (--CALL_API_count>0) \ + /*Restore backup*/ \ + PublicMetaGlobals = backup_meta_globals; \ + if(status==MRES_OVERRIDE) { \ + META_DEBUG(loglevel, ("Returning (override) %s()", pfn_string)); \ + return(override_ret); \ + } \ + else \ + return(orig_ret); + +// ===== end macros =========================================================== + + +#endif /* METAMOD_H */ diff --git a/sdk/metamod/mhook.h b/sdk/metamod/mhook.h new file mode 100644 index 0000000..e87a644 --- /dev/null +++ b/sdk/metamod/mhook.h @@ -0,0 +1,160 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +#ifdef UNFINISHED + +// mhook.h - class and types to describe hooks and hooklists + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MHOOK_H +#define MHOOK_H + +#include "plinfo.h" // plid_t, etc +#include "types_meta.h" // mBOOL +#include "osdep.h" // MUTEX_T, etc + +#define MAX_HOOKS 100 + +// Particular game events that we detect, though whatever means we can best +// find. +typedef enum { + EV_NONE = 0, // no event here... + // non-log detected + EV_PLAYER_CONNECT, // ie ClientConnect + EV_PLAYER_ENTER, // ie ClientPutInServer + EV_PLAYER_LEAVE, // ie ClientDisconnect (opposite PutInServer) + EV_PLAYER_SPAWN, // deadflag change to DEAD_NO + EV_PLAYER_DEATH, // deadflag change to DEAD_DEAD + EV_PLAYER_CHANGE_NAME, // netname change in ClientUserInfoChanged + // log detected + EV_PLAYER_JOIN_TEAM, // ie "Joe<15><785><>" joined team "CT" + EV_PLAYER_SUICIDE, // ie "Joe<15><785>" committed suicide ... + EV_PLAYER_CHANGE_ROLE, // TFC: ie "Joe<15><785>" changed role to "Pyro" + EV_TEAM_KILL, // ie "Joe<15><785>" killed "Bob<16><342>" ... + EV_WEAPON_KILL, // ie "Joe<15><785>" killed "Sam<17><197>" with "sg552" + EV_TEAM_SCORE, // ie Team "CT" scored "7" with "2" players +} game_event_t; + +// Info corresponding to a player, in particular the info found in the logline. +typedef struct { + char *name; + int userid; + int wonid; + char *team; +} event_player_t; + +// Info for an event, mostly corresponding to info from a logline. +typedef struct { + game_event_t evtype; // specific event, if identified. + char *buf; // copy of the logmsg, with embedded NULLs + event_player_t *player; + char *action; // "triggered" string, or a generic action string + event_player_t *target; + char *with; +} event_args_t; + +// Types for callback functions to be called for requested event/logline. +typedef void (*event_func_t) (game_event_t event, event_args_t *args, + const char *logline); +typedef void (*logmatch_func_t) (const char *pattern, event_args_t *args, + const char *logline); + +// The 4 types of hook requests we accept. +typedef enum { + H_NONE = 0, + H_EVENT, // Specific event, from a short list. + H_TRIGGER, // A given "triggered" string. + H_STRING, // Any substring of logline. + H_REGEX, // A regular expression matching of logline. +} hook_t; + + +// Class for individual hook function, as registered by a plugin. +class MHook { + friend class MHookList; + friend class MFuncQueue; + private: + // data: + int index; + hook_t type; // EVENT, TRIGGER, etc + plid_t plid; + int pl_index; // index of matching plugin + void *pfnHandle; + game_event_t event; // if type is H_EVENT + const char *match; // if type is TRIGGER, STRING, or REGEX + // Copy/Assignment constructors, to satisfy -Weffc++. + // Note however, we declare them private and don't define them, since + // we don't ever want to copy or assign instances of the class. + // (thanks to O'Reilly "C++: The Core Language", page 113) + MHook(const MHook &src); + void operator=(const MHook &src); + // constructors: + MHook(void); + MHook(int idx, plid_t pid, game_event_t evt, event_func_t pfn); + MHook(int idx, plid_t pid, hook_t tp, const char *cp, logmatch_func_t pfn); + // functions: + mBOOL call(event_args_t *args, const char *logline); + mBOOL enqueue(MFuncQueue *mfq, event_args_t *args, const char *logline); + public: + // no public interfaces; everything done from friend MHookList. +}; + + +// Class for list of registered hook functions. +class MHookList { + private: + // data: + MHook *hlist[MAX_HOOKS]; + int size; // set to MAX_HOOKS in constructor + int endlist; + MUTEX_T mx_hlist; + int MXlock(void) { return(MUTEX_LOCK(&mx_hlist)); }; + int MXunlock(void) { return(MUTEX_UNLOCK(&mx_hlist)); }; + public: + // constructor: + MHookList(void); + // functions: + int add(plid_t plid, game_event_t event, event_func_t pfnHandle); + int add(plid_t plid, hook_t type, const char *match, + logmatch_func_t pfnHandle); + mBOOL remove(plid_t plid, int hindex); + int remove_all(plid_t plid); + mBOOL call(event_args_t *args, const char *logline); + mBOOL enqueue(MFuncQueue *mfq, hook_t htype, event_args_t *evargs, + const char *logline); + char *str_htype(hook_t htype); +}; + +#endif /* MHOOK_H */ + +#endif /* UNFINISHED */ diff --git a/sdk/metamod/mlist.h b/sdk/metamod/mlist.h new file mode 100644 index 0000000..e997fe4 --- /dev/null +++ b/sdk/metamod/mlist.h @@ -0,0 +1,90 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// mlist.h - class and constants to describe a list of plugins + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MLIST_H +#define MLIST_H + +#include "types_meta.h" // mBOOL +#include "mplugin.h" // class MPlugin +#include "plinfo.h" // plid_t, etc + +// Max number of plugins we can manage. This is an arbitrary, fixed number, +// for convenience. It would probably be better to dynamically grow the +// list as needed, but we do this for now. +#define MAX_PLUGINS 50 +// Width required to printf above MAX, for show() functions. +#define WIDTH_MAX_PLUGINS 2 + + +// A list of plugins. +class MPluginList { + public: + // data: + char inifile[PATH_MAX]; // full pathname + MPlugin plist[MAX_PLUGINS]; // array of plugins + int size; // size of list, ie MAX_PLUGINS + int endlist; // index of last used entry + + // constructor: + MPluginList(const char *ifile); + + // functions: + MPlugin *find(int pindex); // find by index + MPlugin *find(const char *findpath); // find by pathname + MPlugin *find(plid_t id); // find by plid_t + MPlugin *find_memloc(void *memptr); // find by memory location + MPlugin *find_match(const char *prefix); // find by partial prefix match + MPlugin *find_match(MPlugin *pmatch); // find by platform_match() + MPlugin * find(DLHANDLE handle); // find by handle + MPlugin *add(MPlugin *padd); + + mBOOL found_child_plugins(int source_index); + + mBOOL ini_startup(void); // read inifile at startup + mBOOL ini_refresh(void); // re-read inifile + mBOOL cmd_addload(const char *args); // load from console command + MPlugin *plugin_addload(plid_t plid, const char *fname, PLUG_LOADTIME now); //load from plugin + + mBOOL load(void); // load the list, at startup + mBOOL refresh(PLUG_LOADTIME now); // update from re-read inifile + void unpause_all(void); // unpause any paused plugins + void retry_all(PLUG_LOADTIME now); // retry any pending plugin actions + void show(int source_index); // list plugins to console + void show_client(edict_t *pEntity); // list plugins to player client + void clear_source_plugin_index(int source_index); +}; + +#endif /* MLIST_H */ diff --git a/sdk/metamod/mplayer.h b/sdk/metamod/mplayer.h new file mode 100644 index 0000000..931bab4 --- /dev/null +++ b/sdk/metamod/mplayer.h @@ -0,0 +1,91 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// mplayer.h - class to keep info about a player and a class listing all +// players + +/* + * Copyright (c) 2005 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef INCLUDE_METAMOD_PLAYER_H +#define INCLUDE_METAMOD_PLAYER_H + +#include "types_meta.h" // mBOOL + + + +// Numbers of players limit set by the engine +#define MAX_PLAYERS 32 + + + +// Info on an individual player +class MPlayer +{ +private: + mBOOL isQueried; // is this player currently queried for a cvar value + char *cvarName; // name of the cvar if getting queried + + MPlayer (const MPlayer&); + MPlayer& operator=(const MPlayer&); + + +public: + MPlayer(); + ~MPlayer(); + void set_cvar_query(const char *cvar); // mark this player as querying a client cvar + void clear_cvar_query(const char *cvar=NULL); // unmark this player as querying a client cvar + const char *is_querying_cvar(void); // check if a player is querying a cvar. returns + // NULL if not or the name of the cvar +}; + + + +// A list of players. The number of max players is fixed and small enough +// to use an array. +class MPlayerList +{ +private: + enum { NUM_SLOTS = MAX_PLAYERS + 1 }; + + MPlayer players[NUM_SLOTS]; // array of players + + +public: + void set_player_cvar_query(const edict_t *pEntity, const char *cvar); + void clear_player_cvar_query(const edict_t *pEntity, const char *cvar=NULL); + void clear_all_cvar_queries(void); + const char *is_querying_cvar(const edict_t *pEntity); +}; + + +#endif /* INCLUDE_METAMOD_PLAYER_H */ + diff --git a/sdk/metamod/mplugin.h b/sdk/metamod/mplugin.h new file mode 100644 index 0000000..e04e68f --- /dev/null +++ b/sdk/metamod/mplugin.h @@ -0,0 +1,422 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// mplugin.h - class and types to describe an individual plugin + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MPLUGIN_H +#define MPLUGIN_H + +#include // time_t, etc + +#include // DLL_FUNCTIONS, etc + +#include "types_meta.h" // mBOOL +#include "meta_api.h" // GETENTITYAPI_FN, etc +#include "api_info.h" // dllapi_info, etc +#include "support_meta.h" // MAX_DESC_LEN + + +// Flags to indicate current "load" state of plugin. +// NOTE: order is important, as greater/less comparisons are made. +typedef enum { + PL_EMPTY = 0, // empty slot + PL_VALID, // has valid info in it + PL_BADFILE, // nonexistent file (open failed), + // or not a valid plugin file (query failed) + PL_OPENED, // dlopened and queried + PL_FAILED, // opened, but failed to attach or unattach + PL_RUNNING, // attached and running + PL_PAUSED, // attached but paused +} PLUG_STATUS; + +// Action to take for plugin at next opportunity. +typedef enum { + PA_NULL = 0, + PA_NONE, // no action needed right now + PA_KEEP, // keep, after ini refresh + PA_LOAD, // load (dlopen, query) and try to attach + PA_ATTACH, // attach + PA_UNLOAD, // unload (detach, dlclose) + PA_RELOAD, // unload and load again +} PLUG_ACTION; + +// Flags to indicate from where the plugin was loaded. +typedef enum { + PS_INI = 0, // was loaded from the plugins.ini + PS_CMD, // was loaded via a server command + PS_PLUGIN, // was loaded via a plugin +} PLOAD_SOURCE; + +// Flags for how to word description of plugin loadtime. +typedef enum { + SL_SIMPLE = 0, // single word + SL_SHOW, // for "show" output, 5 chars + SL_ALLOWED, // when plugin is allowed to load/unload + SL_NOW, // current situation +} STR_LOADTIME; + +// Flags for how to format description of status. +typedef enum { + ST_SIMPLE = 0, // single word + ST_SHOW, // for "show" output, 4 chars +} STR_STATUS; + +// Flags for how to format description of action. +typedef enum { + SA_SIMPLE = 0, // single word + SA_SHOW, // for "show" output, 4 chars +} STR_ACTION; + +// Flags for how to format description of source. +typedef enum { + SO_SIMPLE = 0, // two words + SO_SHOW, // for "list" output, 3 chars +} STR_SOURCE; + +// An individual plugin. +class MPlugin { + private: + mBOOL query(void); + mBOOL attach(PLUG_LOADTIME now); + mBOOL detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); + gamedll_funcs_t gamedll_funcs; + mutil_funcs_t mutil_funcs; + public: + // data: + int index; // 1-based + char filename[PATH_MAX]; // ie "dlls/mm_test_i386.so", from inifile + char *file; // ie "mm_test_i386.so", ptr from filename + char desc[MAX_DESC_LEN]; // ie "Test metamod plugin", from inifile + char pathname[PATH_MAX]; // UNIQUE, ie "/home/willday/half-life/cstrike/dlls/mm_test_i386.so", built with GameDLL.gamedir + int pfspecific; // level of specific platform affinity, used during load time + PLUG_STATUS status; // current status of plugin (loaded, etc) + PLUG_ACTION action; // what to do with plugin (load, unload, etc) + PLOAD_SOURCE source; // source of the request to load the plugin + + DLHANDLE handle; // handle for dlopen, dlsym, etc + plugin_info_t *info; // information plugin provides about itself + time_t time_loaded; // when plugin was loaded + int source_plugin_index; // who loaded this plugin + int unloader_index; + mBOOL is_unloader; // fix to prevent other plugins unload active unloader. + + DLL_FUNCTIONS *dllapi_table; + DLL_FUNCTIONS *dllapi_post_table; + NEW_DLL_FUNCTIONS *newapi_table; + NEW_DLL_FUNCTIONS *newapi_post_table; + enginefuncs_t *engine_table; + enginefuncs_t *engine_post_table; + + // functions: + + mBOOL ini_parseline(char *line); // parse line from inifile + mBOOL cmd_parseline(const char *line); // parse from console command + mBOOL plugin_parseline(const char *fname, int loader_index); // parse from plugin + mBOOL check_input(void); + + mBOOL resolve(void); // find a matching file on disk + char *resolve_dirs(char *path); + char *resolve_prefix(char *path); + char *resolve_suffix(char *path); + + mBOOL platform_match(MPlugin* plugin); + + mBOOL load(PLUG_LOADTIME now); + mBOOL unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason, PL_UNLOAD_REASON real_reason); + mBOOL reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); + mBOOL pause(void); + mBOOL unpause(void); + mBOOL retry(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); // if previously failed + mBOOL clear(void); + mBOOL plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); // other plugin unloading + void show(void); // print info about plugin to console + + mBOOL newer_file(void); // check for newer file on disk + + // output string functions + char *str_status(STR_STATUS fmt); + char *str_action(STR_ACTION fmt); + char *str_source(STR_SOURCE fmt); + + char *str_reason(PL_UNLOAD_REASON preason, PL_UNLOAD_REASON preal_reason); + char *str_loadtime(PLUG_LOADTIME pallow, STR_LOADTIME fmt); + + char *str_status(void) { return(str_status(ST_SIMPLE)); }; + char *str_action(void) { return(str_action(SA_SIMPLE)); }; + char *str_source(void) { return(str_source(SO_SIMPLE)); }; + + char *str_loadable(void) { + if(info) return(str_loadtime(info->loadable, SL_SIMPLE)); + else return(" -"); + }; + char *str_unloadable(void) { + if(info) return(str_loadtime(info->unloadable, SL_SIMPLE)); + else return(" -"); + }; + char *str_loadable(STR_LOADTIME fmt) { + if(info) return(str_loadtime(info->loadable, fmt)); + else return(" -"); + }; + char *str_unloadable(STR_LOADTIME fmt) { + if(info) return(str_loadtime(info->unloadable, fmt)); + else return(" -"); + }; +}; + +// Macros used by MPlugin::show(), to list the functions that the plugin +// catches. +#define SHOW_IFDEF(api_table, info_table, pfnName, pre_str, post_str) \ + if(api_table->pfnName) { META_CONS("%s%s%s", pre_str, info_table.pfnName.name, post_str); n++;} + +#define SHOW_DEF_DLLAPI(api_table, pre_str, post_str) \ + n=0; \ + SHOW_IFDEF(api_table, dllapi_info, pfnGameInit, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSpawn, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnThink, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnUse, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnTouch, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnBlocked, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnKeyValue, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSave, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnRestore, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSetAbsBox, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSaveWriteFields, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSaveReadFields, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSaveGlobalState, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnRestoreGlobalState, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnResetGlobalState, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnClientConnect, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnClientDisconnect, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnClientKill, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnClientPutInServer, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnClientCommand, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnClientUserInfoChanged, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnServerActivate, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnServerDeactivate, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnPlayerPreThink, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnPlayerPostThink, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnStartFrame, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnParmsNewLevel, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnParmsChangeLevel, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnGetGameDescription, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnPlayerCustomization, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSpectatorConnect, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSpectatorDisconnect, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSpectatorThink, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSys_Error, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnPM_Move, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnPM_Init, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnPM_FindTextureType, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSetupVisibility, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnUpdateClientData, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnAddToFullPack, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnCreateBaseline, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnRegisterEncoders, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnGetWeaponData, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnCmdStart, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnCmdEnd, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnConnectionlessPacket, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnGetHullBounds, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnCreateInstancedBaselines, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnInconsistentFile, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnAllowLagCompensation, pre_str, post_str); + +#define SHOW_DEF_NEWAPI(api_table, pre_str, post_str) \ + n=0; \ + SHOW_IFDEF(api_table, newapi_info, pfnOnFreeEntPrivateData, pre_str, post_str); \ + SHOW_IFDEF(api_table, newapi_info, pfnGameShutdown, pre_str, post_str); \ + SHOW_IFDEF(api_table, newapi_info, pfnShouldCollide, pre_str, post_str); \ + SHOW_IFDEF(api_table, newapi_info, pfnCvarValue, pre_str, post_str); + +#define SHOW_DEF_ENGINE(api_table, pre_str, post_str) \ + n=0; \ + SHOW_IFDEF(api_table, engine_info, pfnPrecacheModel, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPrecacheSound, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetModel, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnModelIndex, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnModelFrames, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetSize, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnChangeLevel, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetSpawnParms, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSaveSpawnParms, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnVecToYaw, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnVecToAngles, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnMoveToOrigin, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnChangeYaw, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnChangePitch, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFindEntityByString, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetEntityIllum, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFindEntityInSphere, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFindClientInPVS, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEntitiesInPVS, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnMakeVectors, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnAngleVectors, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCreateEntity, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnRemoveEntity, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCreateNamedEntity, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnMakeStatic, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEntIsOnFloor, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDropToFloor, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWalkMove, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetOrigin, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEmitSound, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEmitAmbientSound, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTraceLine, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTraceToss, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTraceMonsterHull, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTraceHull, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTraceModel, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTraceTexture, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTraceSphere, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetAimVector, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnServerCommand, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnServerExecute, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnClientCommand, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnParticleEffect, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnLightStyle, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDecalIndex, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPointContents, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnMessageBegin, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnMessageEnd, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteByte, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteChar, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteShort, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteLong, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteAngle, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteCoord, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteString, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteEntity, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCVarRegister, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCVarGetFloat, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCVarGetString, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCVarSetFloat, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCVarSetString, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnAlertMessage, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEngineFprintf, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPvAllocEntPrivateData, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPvEntPrivateData, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFreeEntPrivateData, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSzFromIndex, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnAllocString, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetVarsOfEnt, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPEntityOfEntOffset, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEntOffsetOfPEntity, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnIndexOfEdict, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPEntityOfEntIndex, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFindEntityByVars, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetModelPtr, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnRegUserMsg, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnAnimationAutomove, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetBonePosition, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFunctionFromName, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnNameForFunction, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnClientPrintf, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnServerPrint, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCmd_Args, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCmd_Argv, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCmd_Argc, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetAttachment, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCRC32_Init, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCRC32_ProcessBuffer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCRC32_ProcessByte, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCRC32_Final, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnRandomLong, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnRandomFloat, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetView, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTime, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCrosshairAngle, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnLoadFileForMe, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFreeFile, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEndSection, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCompareFileTime, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetGameDir, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCvar_RegisterVariable, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFadeClientVolume, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetClientMaxspeed, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCreateFakeClient, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnRunPlayerMove, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnNumberOfEntities, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetInfoKeyBuffer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnInfoKeyValue, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetKeyValue, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetClientKeyValue, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnIsMapValid, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnStaticDecal, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPrecacheGeneric, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetPlayerUserId, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnBuildSoundMsg, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnIsDedicatedServer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCVarGetPointer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetPlayerWONId, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnInfo_RemoveKey, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetPhysicsKeyValue, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetPhysicsKeyValue, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetPhysicsInfoString, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPrecacheEvent, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPlaybackEvent, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetFatPVS, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetFatPAS, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCheckVisibility, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDeltaSetField, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDeltaUnsetField, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDeltaAddEncoder, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetCurrentPlayer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCanSkipPlayer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDeltaFindField, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDeltaSetFieldByIndex, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDeltaUnsetFieldByIndex, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetGroupMask, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCreateInstancedBaseline, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCvar_DirectSet, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnForceUnmodified, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetPlayerStats, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnAddServerCommand, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnVoice_GetClientListening, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnVoice_SetClientListening, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetPlayerAuthId, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSequenceGet, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSequencePickSentence, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetFileSize, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetApproxWavePlayLen, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnIsCareerMatch, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetLocalizedStringLength, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnRegisterTutorMessageShown, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetTimesTutorMessageShown, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnProcessTutorMessageDecayBuffer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnConstructTutorMessageDecayBuffer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnResetTutorMessageDecayData, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnQueryClientCvarValue, pre_str, post_str); + + +#endif /* MPLUGIN_H */ diff --git a/sdk/metamod/mqueue.h b/sdk/metamod/mqueue.h new file mode 100644 index 0000000..39eb991 --- /dev/null +++ b/sdk/metamod/mqueue.h @@ -0,0 +1,68 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +#ifdef UNFINISHED + +// mqueue.h - class and types for queues + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MQUEUE_H +#define MQUEUE_H + +#include "plinfo.h" // plid_t, etc +#include "tqueue.h" // templates Queue<>, QItem<>, etc +#include "mhook.h" // event_args_t, etc +#include "types_meta.h" // mBOOL +#include "osdep.h" // MUTEX_T, etc + +// Our queue types. +typedef Queue MLogmsgQueue; + +typedef struct { + MHook *hook; + event_args_t *evargs; + const char *logline; +} func_item_t; + +class MFuncQueue : public Queue { + public: + // renamed constructors: + MFuncQueue(void) :Queue() { }; + MFuncQueue(int qmaxsize) :Queue(qmaxsize) { }; + // added functions: + void remove(plid_t plid); +}; + +#endif /* MQUEUE_H */ + +#endif /* UNFINISHED */ diff --git a/sdk/metamod/mreg.h b/sdk/metamod/mreg.h new file mode 100644 index 0000000..e1c720b --- /dev/null +++ b/sdk/metamod/mreg.h @@ -0,0 +1,186 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// mreg.h - description of registered items (classes MRegCmd, MRegCmdList) + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MREG_H +#define MREG_H + +#include "types_meta.h" // mBOOL + +// Number of entries to add to reglists when they need to grow. Typically +// more cvars than commands, so we grow them at different increments. +#define REG_CMD_GROWSIZE 32 +#define REG_CVAR_GROWSIZE 64 + +// Width required to printf a Reg*List index number, for show() functions. +// This used to correspond to the number of digits in MAX_REG, which was a +// fixed, compile-time limit. However, now that the reg lists are grown +// dynamically, this has less strong correspondance to list sizes. So for +// the moment, it reflects what one might normally expect to be the max +// width needed to print an index number; 4 allows 9999 (which is a damn +// lot, if you ask me). +#define WIDTH_MAX_REG 4 + +// Max number of registered user msgs we can manage. +#define MAX_REG_MSGS 256 + +// Flags to indicate if given cvar or func is part of a loaded plugin. +typedef enum { + RG_INVALID, + RG_VALID, +} REG_STATUS; + +// Pointer to function registered by AddServerCommand. +typedef void (*REG_CMD_FN) (void); + + +// An individual registered function/command. +class MRegCmd { + friend class MRegCmdList; + private: + // data: + int index; // 1-based + public: + char *name; // space is malloc'd + REG_CMD_FN pfnCmd; // pointer to the function + int plugid; // index id of corresponding plugin + REG_STATUS status; // whether corresponding plugin is loaded + // functions: + void init(int idx); // init values, as not using constructors + mBOOL call(void); // try to call the function +}; + + +// A list of registered commands. +class MRegCmdList { + private: + // data: + MRegCmd *mlist; // malloc'd array of registered commands + int size; // current size of list + int endlist; // index of last used entry + // Private; to satisfy -Weffc++ "has pointer data members but does + // not override" copy/assignment constructor. + void operator=(const MRegCmdList &src); + MRegCmdList(const MRegCmdList &src); + + public: + // constructor: + MRegCmdList(void); + + // functions: + MRegCmd *find(const char *findname); // find by MRegCmd->name + MRegCmd *add(const char *addname); + void disable(int plugin_id); // change status to Invalid + void show(void); // list all funcs to console + void show(int plugin_id); // list given plugin's funcs to console +}; + + + +// An individual registered cvar. +class MRegCvar { + friend class MRegCvarList; + private: + // data: + int index; // 1-based + public: + cvar_t *data; // actual cvar structure, malloc'd + int plugid; // index id of corresponding plugin + REG_STATUS status; // whether corresponding plugin is loaded + // functions: + void init(int idx); // init values, as not using constructors + mBOOL set(cvar_t *src); +}; + + +// A list of registered cvars. +class MRegCvarList { + private: + // data: + MRegCvar *vlist; // malloc'd array of registered cvars + int size; // size of list, ie MAX_REG_CVARS + int endlist; // index of last used entry + // Private; to satisfy -Weffc++ "has pointer data members but does + // not override" copy/assignment constructor. + void operator=(const MRegCvarList &src); + MRegCvarList(const MRegCvarList &src); + + public: + // constructor: + MRegCvarList(void); + + // functions: + MRegCvar *add(const char *addname); + MRegCvar *find(const char *findname); // find by MRegCvar->data.name + void disable(int plugin_id); // change status to Invalid + void show(void); // list all cvars to console + void show(int plugin_id); // list given plugin's cvars to console +}; + + + +// An individual registered user msg, from gamedll. +class MRegMsg { + friend class MRegMsgList; + private: + // data: + int index; // 1-based + public: + const char *name; // name, assumed constant string in gamedll + int msgid; // msgid, assigned by engine + int size; // size, if given by gamedll +}; + + +// A list of registered user msgs. +class MRegMsgList { + private: + // data: + MRegMsg mlist[MAX_REG_MSGS]; // array of registered msgs + int size; // size of list, ie MAX_REG_MSGS + int endlist; // index of last used entry + + public: + // constructor: + MRegMsgList(void); + + // functions: + MRegMsg *add(const char *addname, int addmsgid, int addsize); + MRegMsg *find(const char *findname); + MRegMsg *find(int findmsgid); + void show(void); // list all msgs to console +}; + +#endif /* MREG_H */ diff --git a/sdk/metamod/mutil.h b/sdk/metamod/mutil.h new file mode 100644 index 0000000..820851b --- /dev/null +++ b/sdk/metamod/mutil.h @@ -0,0 +1,160 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// mutil.h - prototypes for utility functions to provide to plugins + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MUTIL_H +#define MUTIL_H + +#include "plinfo.h" // plugin_info_t, etc +#include "mhook.h" // game_event_t, etc +#include "sdk_util.h" // hudtextparms_t, etc + +// max buffer size for printed messages +#define MAX_LOGMSG_LEN 1024 + +// For GetGameInfo: +typedef enum { + GINFO_NAME = 0, + GINFO_DESC, + GINFO_GAMEDIR, + GINFO_DLL_FULLPATH, + GINFO_DLL_FILENAME, + GINFO_REALDLL_FULLPATH, +} ginfo_t; + +// Meta Utility Function table type. +typedef struct meta_util_funcs_s { + void (*pfnLogConsole) (plid_t plid, const char *fmt, ...); + void (*pfnLogMessage) (plid_t plid, const char *fmt, ...); + void (*pfnLogError) (plid_t plid, const char *fmt, ...); + void (*pfnLogDeveloper) (plid_t plid, const char *fmt, ...); + void (*pfnCenterSay) (plid_t plid, const char *fmt, ...); + void (*pfnCenterSayParms) (plid_t plid, hudtextparms_t tparms, + const char *fmt, ...); + void (*pfnCenterSayVarargs) (plid_t plid, hudtextparms_t tparms, + const char *fmt, va_list ap); + qboolean (*pfnCallGameEntity) (plid_t plid, const char *entStr, + entvars_t *pev); + int (*pfnGetUserMsgID) (plid_t plid, const char *msgname, int *size); + const char *(*pfnGetUserMsgName) (plid_t plid, int msgid, int *size); + const char *(*pfnGetPluginPath) (plid_t plid); + const char *(*pfnGetGameInfo) (plid_t plid, ginfo_t tag); + int (*pfnLoadPlugin) (plid_t plid, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle); + int (*pfnUnloadPlugin) (plid_t plid, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); + int (*pfnUnloadPluginByHandle) (plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); + const char *(*pfnIsQueryingClientCvar) (plid_t plid, const edict_t *pEdict); + int (*pfnMakeRequestId) (plid_t plid); + void (*pfnGetHookTables) (plid_t plid, enginefuncs_t **peng, DLL_FUNCTIONS **pdll, NEW_DLL_FUNCTIONS **pnewdll); +#ifdef UNFINISHED + int (*pfnHookGameEvent) (plid_t plid, game_event_t event, + event_func_t pfnHandle); + int (*pfnHookLogTrigger) (plid_t plid, const char *trigger, + logmatch_func_t pfnHandle); + int (*pfnHookLogString) (plid_t plid, const char *string, + logmatch_func_t pfnHandle); + int (*pfnHookLogRegex) (plid_t plid, const char *pattern, + logmatch_func_t pfnHandle); + qboolean (*pfnRemoveHookID) (plid_t plid, int hookid); + int (*pfnRemoveHookAll) (plid_t plid); +#endif /* UNFINISHED */ +} mutil_funcs_t; +extern mutil_funcs_t MetaUtilFunctions; + +// Meta Utility Functions +void mutil_LogConsole(plid_t plid, const char *fmt, ...); +void mutil_LogMessage(plid_t plid, const char *fmt, ...); +void mutil_LogError(plid_t plid, const char *fmt, ...); +void mutil_LogDeveloper(plid_t plid, const char *fmt, ...); + +void mutil_CenterSay(plid_t plid, const char *fmt, ...); +void mutil_CenterSayParms(plid_t plid, hudtextparms_t tparms, + const char *fmt, ...); +void mutil_CenterSayVarargs(plid_t plid, hudtextparms_t tparms, + const char *fmt, va_list ap); + +qboolean mutil_CallGameEntity(plid_t plid, const char *entStr, entvars_t *pev); + +int mutil_GetUserMsgID(plid_t plid, const char *name, int *size); +const char *mutil_GetUserMsgName(plid_t plid, int msgid, int *size); +const char *mutil_GetPluginPath(plid_t plid); +const char *mutil_GetGameInfo(plid_t plid, ginfo_t tag); +const char *mutil_IsQueryingClientCvar(plid_t plid, const edict_t *pEdict); +int mutil_MakeRequestId(plid_t plid); +void mutil_GetHookTables(plid_t plid, enginefuncs_t **peng, DLL_FUNCTIONS **pdll, NEW_DLL_FUNCTIONS **pnewdll); + +#ifdef UNFINISHED +int mutil_HookGameEvent(plid_t plid, game_event_t event, + event_func_t pfnHandle); +int mutil_HookLogTrigger(plid_t plid, const char *trigger, + logmatch_func_t pfnHandle); +int mutil_HookLogString(plid_t plid, const char *string, + logmatch_func_t pfnHandle); +int mutil_HookLogRegex(plid_t plid, const char *pattern, + logmatch_func_t pfnHandle); + +qboolean mutil_RemoveHookID(plid_t plid, int hookid); +int mutil_RemoveHookAll(plid_t plid); +#endif /* UNFINISHED */ + +// Convenience macros for MetaUtil functions +#define LOG_CONSOLE (*gpMetaUtilFuncs->pfnLogConsole) +#define LOG_MESSAGE (*gpMetaUtilFuncs->pfnLogMessage) +#define LOG_ERROR (*gpMetaUtilFuncs->pfnLogError) +#define LOG_DEVELOPER (*gpMetaUtilFuncs->pfnLogDeveloper) +#define CENTER_SAY (*gpMetaUtilFuncs->pfnCenterSay) +#define CENTER_SAY_PARMS (*gpMetaUtilFuncs->pfnCenterSayParms) +#define CENTER_SAY_VARARGS (*gpMetaUtilFuncs->pfnCenterSayVarargs) +#define CALL_GAME_ENTITY (*gpMetaUtilFuncs->pfnCallGameEntity) +#define GET_USER_MSG_ID (*gpMetaUtilFuncs->pfnGetUserMsgID) +#define GET_USER_MSG_NAME (*gpMetaUtilFuncs->pfnGetUserMsgName) +#define GET_PLUGIN_PATH (*gpMetaUtilFuncs->pfnGetPluginPath) +#define GET_GAME_INFO (*gpMetaUtilFuncs->pfnGetGameInfo) +#define LOAD_PLUGIN (*gpMetaUtilFuncs->pfnLoadPlugin) +#define UNLOAD_PLUGIN (*gpMetaUtilFuncs->pfnUnloadPlugin) +#define UNLOAD_PLUGIN_BY_HANDLE (*gpMetaUtilFuncs->pfnUnloadPluginByHandle) +#define IS_QUERYING_CLIENT_CVAR (*gpMetaUtilFuncs->pfnIsQueryingClientCvar) +#define MAKE_REQUESTID (*gpMetaUtilFuncs->pfnMakeRequestId) +#define GET_HOOK_TABLES (*gpMetaUtilFuncs->pfnGetHookTables) + +#ifdef UNFINISHED +#define HOOK_GAME_EVENT (*gpMetaUtilFuncs->pfnHookGameEvent) +#define HOOK_LOG_TRIGGER (*gpMetaUtilFuncs->pfnHookLogTrigger) +#define HOOK_LOG_STRING (*gpMetaUtilFuncs->pfnHookLogString) +#define HOOK_LOG_REGEX (*gpMetaUtilFuncs->pfnHookLogRegex) +#define REMOVE_HOOK_ID (*gpMetaUtilFuncs->pfnRemoveHookID) +#define REMOVE_HOOK_ALL (*gpMetaUtilFuncs->pfnRemoveHookAll) +#endif /* UNFINISHED */ + +#endif /* MUTIL_H */ diff --git a/sdk/metamod/osdep.h b/sdk/metamod/osdep.h new file mode 100644 index 0000000..32dc8db --- /dev/null +++ b/sdk/metamod/osdep.h @@ -0,0 +1,522 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// osdep.h - operating system dependencies + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef OSDEP_H +#define OSDEP_H + +#include // strerror() +#include // isupper, tolower +#include // errno + +// Various differences between WIN32 and Linux. + +#include "types_meta.h" // mBOOL +#include "mreg.h" // REG_CMD_FN, etc +#include "log_meta.h" // LOG_ERROR, etc + +extern mBOOL dlclose_handle_invalid; + +// String describing platform/DLL-type, for matching lines in plugins.ini. +#ifdef linux + #define PLATFORM "linux" +# ifdef __amd64__ + #define PLATFORM_SPC "lin64" +# else + #define PLATFORM_SPC "lin32" +# endif +#elif defined(_WIN32) + #define PLATFORM "mswin" + #define PLATFORM_SPC "win32" +#else /* unknown */ + #error "OS unrecognized" +#endif /* unknown */ + + +// Macro for function-exporting from DLL.. +// from SDK dlls/cbase.h: +//! C functions for external declarations that call the appropriate C++ methods + +// Windows uses "__declspec(dllexport)" to mark functions in the DLL that +// should be visible/callable externally. +// +// It also apparently requires WINAPI for GiveFnptrsToDll(). +// +// See doc/notes_windows_coding for more information.. + +// Attributes to specify an "exported" function, visible from outside the +// DLL. +#undef DLLEXPORT +#ifdef _WIN32 + #define DLLEXPORT __declspec(dllexport) + // WINAPI should be provided in the windows compiler headers. + // It's usually defined to something like "__stdcall". +#elif defined(linux) + #define DLLEXPORT /* */ + #define WINAPI /* */ +#endif /* linux */ + +#ifdef __GNUC__ +# define DECLSPEC(kw) +# define ATTRIBUTE(kw) __attribute__((kw)) +# define MM_CDECL +#elif defined(_MSC_VER) +# define DECLSPEC(kw) __declspec(kw) +# define ATTRIBUTE(kw) +# define MM_CDECL __cdecl +#endif /* _MSC_VER */ + + +// Simplified macro for declaring/defining exported DLL functions. They +// need to be 'extern "C"' so that the C++ compiler enforces parameter +// type-matching, rather than considering routines with mis-matched +// arguments/types to be overloaded functions... +// +// AFAIK, this is os-independent, but it's included here in osdep.h where +// DLLEXPORT is defined, for convenience. +#define C_DLLEXPORT extern "C" DLLEXPORT + + +#ifdef _MSC_VER + // Disable MSVC warning: + // 4390 : empty controlled statement found; is this what was intended? + // generated by the RETURN macros. + #pragma warning(disable: 4390) +#endif /* _MSC_VER */ + + +// Functions & types for DLL open/close/etc operations. +#ifdef linux + #include + typedef void* DLHANDLE; + typedef void* DLFUNC; + inline DLHANDLE DLOPEN(const char *filename) { + return(dlopen(filename, RTLD_NOW)); + } + inline DLFUNC DLSYM(DLHANDLE handle, const char *string) { + return(dlsym(handle, string)); + } + inline int DLCLOSE(DLHANDLE handle) { + if (!handle) { + dlclose_handle_invalid = mTRUE; + return(1); + } + dlclose_handle_invalid = mFALSE; + return(dlclose(handle)); + } + inline const char* DLERROR(void) { + if (dlclose_handle_invalid) + return("Invalid handle."); + return(dlerror()); + } +#elif defined(_WIN32) + typedef HINSTANCE DLHANDLE; + typedef FARPROC DLFUNC; + inline DLHANDLE DLOPEN(const char *filename) { + return(LoadLibrary(filename)); + } + inline DLFUNC DLSYM(DLHANDLE handle, const char *string) { + return(GetProcAddress(handle, string)); + } + inline int DLCLOSE(DLHANDLE handle) { + if (!handle) { + dlclose_handle_invalid = mTRUE; + return(1); + } + dlclose_handle_invalid = mFALSE; + // NOTE: Windows FreeLibrary returns success=nonzero, fail=zero, + // which is the opposite of the unix convention, thus the '!'. + return(!FreeLibrary(handle)); + } + // Windows doesn't provide a function corresponding to dlerror(), so + // we make our own. + char *str_GetLastError(void); + inline char* DLERROR(void) { + if (dlclose_handle_invalid) + return("Invalid handle."); + return(str_GetLastError()); + } +#endif /* _WIN32 */ +const char *DLFNAME(void *memptr); +mBOOL IS_VALID_PTR(void *memptr); + + +// Attempt to call the given function pointer, without segfaulting. +mBOOL os_safe_call(REG_CMD_FN pfn); + + +// Windows doesn't have an strtok_r() routine, so we write our own. +#ifdef _WIN32 + #define strtok_r(s, delim, ptrptr) my_strtok_r(s, delim, ptrptr) + char *my_strtok_r(char *s, const char *delim, char **ptrptr); +#endif /* _WIN32 */ + + +// Set filename and pathname maximum lengths. Note some windows compilers +// provide a which is incomplete and/or causes problems; see +// doc/windows_notes.txt for more information. +// +// Note that both OS's include room for null-termination: +// linux: "# chars in a path name including nul" +// win32: "note that the sizes include space for 0-terminator" +#ifdef linux + #include +#elif defined(_WIN32) + #include + #define NAME_MAX _MAX_FNAME + #define PATH_MAX _MAX_PATH +#endif /* _WIN32 */ + + +// Various other windows routine differences. +#ifdef linux + #include // sleep + #ifndef O_BINARY + #define O_BINARY 0 + #endif +#elif defined(_WIN32) + #define snprintf _snprintf + #define vsnprintf _vsnprintf + #define sleep(x) Sleep(x*1000) + #define strcasecmp _stricmp + #define strncasecmp _strnicmp + #include + #define open _open + #define read _read + #define write _write + #define close _close +#endif /* _WIN32 */ + +#ifdef __GNUC__ + #include // getcwd +#elif defined(_MSC_VER) + #include // getcwd +#endif /* _MSC_VER */ + +#include +#ifndef S_ISREG + // Linux gcc defines this; earlier mingw didn't, later mingw does; + // MSVC doesn't seem to. + #define S_ISREG(m) ((m) & S_IFREG) +#endif /* not S_ISREG */ +#ifdef _WIN32 + // The following two are defined in mingw but not in MSVC + #ifndef S_IRUSR + #define S_IRUSR _S_IREAD + #endif + #ifndef S_IWUSR + #define S_IWUSR _S_IWRITE + #endif + + // The following two are defined neither in mingw nor in MSVC + #ifndef S_IRGRP + #define S_IRGRP S_IRUSR + #endif + #ifndef S_IWGRP + #define S_IWGRP S_IWUSR + #endif +#endif /* _WIN32 */ + + +// Our handler for new(). +// +// Thanks to notes from: +// http://dragon.klte.hu/~kollarl/C++/node45.html +// +// At one point it appeared MSVC++ was no longer different from gcc, according +// to: +// http://msdn.microsoft.com/library/en-us/vclang98/stdlib/info/NEW.asp +// +// However, this page is apparently no longer available from MSDN. The +// only thing now is: +// http://msdn.microsoft.com/library/en-us/vccore98/HTML/_crt_malloc.asp +// +// According to Fritz Elfert : +// set_new_handler() is just a stub which (according to comments in the +// MSVCRT debugging sources) should never be used. It is just an ugly +// hack to make STL compile. It does _not_ set the new handler but +// always calls _set_new_handler(0) instead. _set_new_handler is the +// "real" function and uses the "old" semantic; handler-type is: +// int newhandler(size_t) +// +#if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 1300)) + void MM_CDECL meta_new_handler(void); +#elif defined(_MSC_VER) + int meta_new_handler(size_t size); +#endif /* _MSC_VER */ + + +// To keep the rest of the sources clean and keep not only OS but also +// compiler dependant differences in this file, we define a local function +// to set the new handler. +void mm_set_new_handler( void ); + + + +// Thread handling... +#ifdef linux + #include + typedef pthread_t THREAD_T; + // returns 0==success, non-zero==failure + inline int THREAD_CREATE(THREAD_T *tid, void (*func)(void)) { + int ret; + ret=pthread_create(tid, NULL, (void *(*)(void*)) func, NULL); + if(ret != 0) { + META_ERROR("Failure starting thread: %s", strerror(ret)); + return(ret); + } + ret=pthread_detach(*tid); + if(ret != 0) + META_ERROR("Failure detaching thread: %s", strerror(ret)); + return(ret); + } +#elif defined(_WIN32) + // See: + // http://msdn.microsoft.com/library/en-us/dllproc/prothred_4084.asp + typedef DWORD THREAD_T; + // returns 0==success, non-zero==failure + inline int THREAD_CREATE(THREAD_T *tid, void (*func)(void)) { + HANDLE ret; + // win32 returns NULL==failure, non-NULL==success + ret=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) func, NULL, 0, tid); + if(ret==NULL) + META_ERROR("Failure starting thread: %s", str_GetLastError()); + return(ret==NULL); + } +#endif /* _WIN32 */ +#define THREAD_OK 0 + + +// Mutex handling... +#ifdef linux + typedef pthread_mutex_t MUTEX_T; + inline int MUTEX_INIT(MUTEX_T *mutex) { + int ret; + ret=pthread_mutex_init(mutex, NULL); + if(ret!=THREAD_OK) + META_ERROR("mutex_init failed: %s", strerror(ret)); + return(ret); + } + inline int MUTEX_LOCK(MUTEX_T *mutex) { + int ret; + ret=pthread_mutex_lock(mutex); + if(ret!=THREAD_OK) + META_ERROR("mutex_lock failed: %s", strerror(ret)); + return(ret); + } + inline int MUTEX_UNLOCK(MUTEX_T *mutex) { + int ret; + ret=pthread_mutex_unlock(mutex); + if(ret!=THREAD_OK) + META_ERROR("mutex_unlock failed: %s", strerror(ret)); + return(ret); + } +#elif defined(_WIN32) + // Win32 has "mutexes" as well, but CS's are simpler. + // See: + // http://msdn.microsoft.com/library/en-us/dllproc/synchro_2a2b.asp + typedef CRITICAL_SECTION MUTEX_T; + // Note win32 routines don't return any error (return void). + inline int MUTEX_INIT(MUTEX_T *mutex) { + InitializeCriticalSection(mutex); + return(THREAD_OK); + } + inline int MUTEX_LOCK(MUTEX_T *mutex) { + EnterCriticalSection(mutex); + return(THREAD_OK); + } + inline int MUTEX_UNLOCK(MUTEX_T *mutex) { + LeaveCriticalSection(mutex); + return(THREAD_OK); + } +#endif /* _WIN32 (mutex) */ + + +// Condition variables... +#ifdef linux + typedef pthread_cond_t COND_T; + inline int COND_INIT(COND_T *cond) { + int ret; + ret=pthread_cond_init(cond, NULL); + if(ret!=THREAD_OK) + META_ERROR("cond_init failed: %s", strerror(ret)); + return(ret); + } + inline int COND_WAIT(COND_T *cond, MUTEX_T *mutex) { + int ret; + ret=pthread_cond_wait(cond, mutex); + if(ret!=THREAD_OK) + META_ERROR("cond_wait failed: %s", strerror(ret)); + return(ret); + } + inline int COND_SIGNAL(COND_T *cond) { + int ret; + ret=pthread_cond_signal(cond); + if(ret!=THREAD_OK) + META_ERROR("cond_signal failed: %s", strerror(ret)); + return(ret); + } +#elif defined(_WIN32) + // Since win32 doesn't provide condition-variables, we have to model + // them with mutex/critical-sections and win32 events. This uses the + // second (SetEvent) solution from: + // + // http://www.cs.wustl.edu/~schmidt/win32-cv-1.html + // + // but without the waiters_count overhead, since we don't need + // broadcast functionality anyway. Or actually, I guess it's more like + // the first (PulseEvent) solution, but with SetEven rather than + // PulseEvent. :) + // + // See also: + // http://msdn.microsoft.com/library/en-us/dllproc/synchro_8ann.asp + typedef HANDLE COND_T; + inline int COND_INIT(COND_T *cond) { + *cond = CreateEvent(NULL, // security attributes (none) + FALSE, // manual-reset type (false==auto-reset) + FALSE, // initial state (unsignaled) + NULL); // object name (unnamed) + // returns NULL on error + if(*cond==NULL) { + META_ERROR("cond_init failed: %s", str_GetLastError()); + return(-1); + } + else + return(0); + } + inline int COND_WAIT(COND_T *cond, MUTEX_T *mutex) { + DWORD ret; + LeaveCriticalSection(mutex); + ret=WaitForSingleObject(*cond, INFINITE); + EnterCriticalSection(mutex); + // returns WAIT_OBJECT_0 if object was signaled; other return + // values indicate errors. + if(ret == WAIT_OBJECT_0) + return(0); + else { + META_ERROR("cond_wait failed: %s", str_GetLastError()); + return(-1); + } + } + inline int COND_SIGNAL(COND_T *cond) { + BOOL ret; + ret=SetEvent(*cond); + // returns zero on failure + if(ret==0) { + META_ERROR("cond_signal failed: %s", str_GetLastError()); + return(-1); + } + else + return(0); + } +#endif /* _WIN32 (condition variable) */ + +// Normalize/standardize a pathname. +// - For win32, this involves: +// - Turning backslashes (\) into slashes (/), so that config files and +// Metamod internal code can be simpler and just use slashes (/). +// - Turning upper/mixed case into lowercase, since windows is +// non-case-sensitive. +// - For linux, this requires no work, as paths uses slashes (/) natively, +// and pathnames are case-sensitive. +#ifdef linux +#define normalize_pathname(a) +#elif defined(_WIN32) +inline void normalize_pathname(char *path) { + char *cp; + + META_DEBUG(8, ("normalize: %s", path)); + for(cp=path; *cp; cp++) { + if(isupper(*cp)) *cp=tolower(*cp); + if(*cp=='\\') *cp='/'; + } + META_DEBUG(8, ("normalized: %s", path)); +} +#endif /* _WIN32 */ + +// Indicate if pathname appears to be an absolute-path. Under linux this +// is a leading slash (/). Under win32, this can be: +// - a drive-letter path (ie "D:blah" or "C:\blah") +// - a toplevel path (ie "\blah") +// - a UNC network address (ie "\\srv1\blah"). +// Also, handle both native and normalized pathnames. +inline int is_absolute_path(const char *path) { + if(path[0]=='/') return(TRUE); +#ifdef _WIN32 + if(path[1]==':') return(TRUE); + if(path[0]=='\\') return(TRUE); +#endif /* _WIN32 */ + return(FALSE); +} + +#ifdef _WIN32 +// Buffer pointed to by resolved_name is assumed to be able to store a +// string of PATH_MAX length. +inline char *realpath(const char *file_name, char *resolved_name) { + int ret; + ret=GetFullPathName(file_name, PATH_MAX, resolved_name, NULL); + if(ret > PATH_MAX) { + errno=ENAMETOOLONG; + return(NULL); + } + else if(ret > 0) { + HANDLE handle; + WIN32_FIND_DATA find_data; + handle=FindFirstFile(resolved_name, &find_data); + if(INVALID_HANDLE_VALUE == handle) { + errno=ENOENT; + return NULL; + } + FindClose(handle); + normalize_pathname(resolved_name); + return(resolved_name); + } + else + return(NULL); +} +#endif /* _WIN32 */ + +// Generic "error string" from a recent OS call. For linux, this is based +// on errno. For win32, it's based on GetLastError. +inline const char *str_os_error(void) { +#ifdef linux + return(strerror(errno)); +#elif defined(_WIN32) + return(str_GetLastError()); +#endif /* _WIN32 */ +} + + +#endif /* OSDEP_H */ diff --git a/sdk/metamod/plinfo.h b/sdk/metamod/plinfo.h new file mode 100644 index 0000000..40303ab --- /dev/null +++ b/sdk/metamod/plinfo.h @@ -0,0 +1,82 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// plinfo.h - typedefs for plugin info structure + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef PLINFO_H +#define PLINFO_H + +// Flags for plugin to indicate when it can be be loaded/unloaded. +// NOTE: order is crucial, as greater/less comparisons are made. +typedef enum { + PT_NEVER = 0, + PT_STARTUP, // should only be loaded/unloaded at initial hlds execution + PT_CHANGELEVEL, // can be loaded/unloaded between maps + PT_ANYTIME, // can be loaded/unloaded at any time + PT_ANYPAUSE, // can be loaded/unloaded at any time, and can be "paused" during a map +} PLUG_LOADTIME; + +// Flags to indicate why the plugin is being unloaded. +typedef enum { + PNL_NULL = 0, + PNL_INI_DELETED, // was deleted from plugins.ini + PNL_FILE_NEWER, // file on disk is newer than last load + PNL_COMMAND, // requested by server/console command + PNL_CMD_FORCED, // forced by server/console command + PNL_DELAYED, // delayed from previous request; can't tell origin +//only used for 'real_reason' on MPlugin::unload() + PNL_PLUGIN, // requested by plugin function call + PNL_PLG_FORCED, // forced by plugin function call + PNL_RELOAD, // forced unload by reload() +} PL_UNLOAD_REASON; + +// Information plugin provides about itself. +typedef struct { + char *ifvers; // meta_interface version + char *name; // full name of plugin + char *version; // version + char *date; // date + char *author; // author name/email + char *url; // URL + char *logtag; // log message prefix (unused right now) + PLUG_LOADTIME loadable; // when loadable + PLUG_LOADTIME unloadable; // when unloadable +} plugin_info_t; +extern plugin_info_t Plugin_info; + +// Plugin identifier, passed to all Meta Utility Functions. +typedef plugin_info_t* plid_t; +#define PLID &Plugin_info + +#endif /* PLINFO_H */ diff --git a/sdk/metamod/reg_support.h b/sdk/metamod/reg_support.h new file mode 100644 index 0000000..57d07c6 --- /dev/null +++ b/sdk/metamod/reg_support.h @@ -0,0 +1,48 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// reg_support.h - functions for "registered" cmd/cvar/msg support + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef REG_SUPPORT_H +#define REG_SUPPORT_H + +#include "mreg.h" // REG_CMD_FN, etc + +void meta_command_handler(void); +void meta_AddServerCommand(char *cmd_name, REG_CMD_FN function); +void meta_CVarRegister(cvar_t *pCvar); +int meta_RegUserMsg(const char *pszName, int iSize); +void meta_QueryClientCvarValue(const edict_t *player, const char *cvarName); + +#endif /* REG_SUPPORT_H */ diff --git a/sdk/metamod/sdk_util.h b/sdk/metamod/sdk_util.h new file mode 100644 index 0000000..15964a9 --- /dev/null +++ b/sdk/metamod/sdk_util.h @@ -0,0 +1,115 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// sdk_util.h - wrapper & extension of util.h from HL SDK + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +// Wrap util.h from SDK with ifndef/endif, to avoid problems from multiple +// inclusions. Dunno why Valve didn't do that in util.h themselves.. + +#ifndef SDK_UTIL_H +#define SDK_UTIL_H + +// We're not including the DBG_EntOfVars and DBG_AssertFunction routines +// mentioned in the SDK util.h, so we're going to unset DEBUG here so that +// we don't get "unresolved symbol" errors. +#ifdef DEBUG +#undef DEBUG +#endif /* DEBUG */ + +// Inlcude local enginecallbacks wrapper *first* so that the g_engfuncs +// type is correct and the header protection is already +// defined. +#include "enginecallbacks.h" + +#include + + + +// Add overloaded ENTINDEX() version for const edict_t pointer. +// The pfnIndexOfEdict() function takes a const edict_t pointer +// as parameter anyway, so there is no reason why ENTINDEX() +// shouldn't. +inline int ENTINDEX(const edict_t *pEdict) { + return (*g_engfuncs.pfnIndexOfEdict)(pEdict); +} + + +// Also, create some nice inlines for engine callback combos. + +// Get a setinfo value from a player entity. +inline char *ENTITY_KEYVALUE(edict_t *entity, char *key) { + char *ifbuf=GET_INFOKEYBUFFER(entity); + return(INFOKEY_VALUE(ifbuf, key)); +} + +// Set a setinfo value for a player entity. +inline void ENTITY_SET_KEYVALUE(edict_t *entity, char *key, char *value) { + char *ifbuf=GET_INFOKEYBUFFER(entity); + SET_CLIENT_KEYVALUE(ENTINDEX(entity), ifbuf, key, value); +} + +// Get a "serverinfo" value. +inline char *SERVERINFO(char *key) { + edict_t *server=INDEXENT(0); + return(ENTITY_KEYVALUE(server, key)); +} + +// Set a "serverinfo" value. +inline void SET_SERVERINFO(char *key, char *value) { + edict_t *server=INDEXENT(0); + char *ifbuf=GET_INFOKEYBUFFER(server); + SET_SERVER_KEYVALUE(ifbuf, key, value); +} + +// Get a "localinfo" value. +inline char *LOCALINFO(char *key) { + edict_t *server=NULL; + return(ENTITY_KEYVALUE(server, key)); +} + +// Set a "localinfo" value. +inline void SET_LOCALINFO(char *key, char *value) { + edict_t *server=NULL; + char *ifbuf=GET_INFOKEYBUFFER(server); + SET_SERVER_KEYVALUE(ifbuf, key, value); +} + +short FixedSigned16(float value, float scale); +unsigned short FixedUnsigned16(float value, float scale); + +// Our slightly modified version, using an edict_t pointer instead of a +// CBaseEntity pointer. +void META_UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage); + +#endif /* SDK_UTIL_H */ diff --git a/sdk/metamod/studioapi.h b/sdk/metamod/studioapi.h new file mode 100644 index 0000000..00aff62 --- /dev/null +++ b/sdk/metamod/studioapi.h @@ -0,0 +1,56 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// studio.cpp - player model blending interfaces + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef STUDIOAPI_H +#define STUDIOAPI_H + +#include // MAXSTUDIOBONES + +// Typedef for Server_GetBlendingInterface() from Eric Smith on the hlcoders +// mailing list. +typedef int (*GETBLENDAPI_FN) (int version, + struct sv_blending_interface_s **ppinterface, + struct engine_studio_api_s *pstudio, + float (*rotationmatrix)[3][4], + float (*bonetransform)[MAXSTUDIOBONES][3][4]); + +extern int mm_Server_GetBlendingInterface(int version, + struct sv_blending_interface_s **ppinterface, + struct engine_studio_api_s *pstudio, + float (*rotationmatrix)[3][4], + float (*bonetransform)[MAXSTUDIOBONES][3][4]); + +#endif /* STUDIOAPI_H */ diff --git a/sdk/metamod/support_meta.h b/sdk/metamod/support_meta.h new file mode 100644 index 0000000..870b6ee --- /dev/null +++ b/sdk/metamod/support_meta.h @@ -0,0 +1,148 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// support_meta.h - generic support macros + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef SUPPORT_META_H +#define SUPPORT_META_H + +#include // strcpy(), strncat() +#include // stat +#include // stat + +#include "osdep.h" // strcasecmp, S_ISREG, + +void do_exit(int exitval) ATTRIBUTE(__noreturn__); + +// Unlike snprintf(), strncpy() doesn't necessarily null-terminate the +// target. It appears the former function reasonably considers the given +// size to be "max size of target string" (including the null-terminator), +// whereas strncpy() strangely considers the given size to be "total number +// of bytes to copy". Note strncpy() _always_ writes n bytes, whereas +// snprintf() writes a _max_ of n bytes (incl the NULL). If strncpy() +// needs to write extra bytes to reach n, it uses NULLs, so the target +// _can_ be null-terminated, but only if the source string would have fit +// anyway - in which case why not just use strcpy() instead? +// +// Thus, it appears strncpy() is not only unsafe, it's also inefficient, +// and seemingly no better than plain strcpy() anyway. +// +// With this logic, strncpy() doesn't appear to be much of a "str" function +// at all, IMHO. +// +// Strncat works better, although it considers the given size to be "number +// of bytes to append", and doesn't include the null-terminator in that +// count. Thus, we can use it for what we want to do, by setting the +// target to zero-length (NULL in first byte), and copying n-1 bytes +// (leaving room for the null-termiator). +// +// Why does it have to be soo haaard... + +// Also note, some kind of wrapper is necessary to group the two +// statements into one, for use in situations like non-braced else +// statements. + +// Technique 1: use "do..while": +#if 0 +#define STRNCPY(dst, src, size) \ + do { strcpy(dst, "\0"); strncat(dst, src, size-1); } while(0) +#endif + +// Technique 2: use parens and commas: +#if 0 +#define STRNCPY(dst, src, size) \ + (strcpy(dst, "\0"), strncat(dst, src, size-1)) +#endif + +// Technique 3: use inline +inline char *STRNCPY(char *dst, const char *src, int size) { + strcpy(dst, "\0"); + return(strncat(dst, src, size-1)); +} + +// Renamed string functions to be clearer. +inline int strmatch(const char *s1, const char *s2) { + if(!s1 || !s2) + return(0); + else + return(!strcmp(s1, s2)); +} +inline int strnmatch(const char *s1, const char *s2, size_t n) { + if(!s1 || !s2) + return(0); + else + return(!strncmp(s1, s2, n)); +} +inline int strcasematch(const char *s1, const char *s2) { + if(!s1 || !s2) + return(0); + else + return(!strcasecmp(s1, s2)); +} +inline int strncasematch(const char *s1, const char *s2, size_t n) { + if(!s1 || !s2) + return(0); + else + return(!strncasecmp(s1, s2, n)); +} + +inline int old_valid_file(char *path) { + char *cp; + int len, ret; + cp = (char *) LOAD_FILE_FOR_ME(path, &len); + if(cp && len) + ret=1; + else + ret=0; + FREE_FILE(cp); + return(ret); +} +int valid_gamedir_file(char *path); +char *full_gamedir_path(const char *path, char *fullpath); + +// Turn a variable/function name into the corresponding string, optionally +// stripping off the leading "len" characters. Useful for things like +// turning 'pfnClientCommand' into "ClientCommand" so we don't have to +// specify strings used for all the debugging/log messages. +#define STRINGIZE(name, len) #name+len + + +// Max description length for plugins.ini and other places. +#define MAX_DESC_LEN 256 + + +// For various character string buffers. +#define MAX_STRBUF_LEN 1024 + +#endif /* SUPPORT_META_H */ diff --git a/sdk/metamod/thread_logparse.h b/sdk/metamod/thread_logparse.h new file mode 100644 index 0000000..c1db423 --- /dev/null +++ b/sdk/metamod/thread_logparse.h @@ -0,0 +1,59 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +#ifdef UNFINISHED + +// thread_logparse.h - prototypes for thread_logparse functions + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef THREAD_LOGPARSE_H +#define THREAD_LOGPARSE_H + +#include "mqueue.h" // Queue template +#include // THREAD_T, etc + +extern MLogmsgQueue *LogQueue; +extern MFuncQueue *HookQueue; + +extern THREAD_T logparse_thread_id; + +void startup_logparse_thread(void); +void WINAPI logparse_handler(void); + +event_args_t *parse_event_args(const char *logline); +event_player_t *parse_player(char *start, int *retlen); +char *parse_quoted(char *start, int *retlen); + +#endif /* THREAD_LOGPARSE_H */ + +#endif /* UNFINISHED */ diff --git a/sdk/metamod/tqueue.h b/sdk/metamod/tqueue.h new file mode 100644 index 0000000..8ec3a89 --- /dev/null +++ b/sdk/metamod/tqueue.h @@ -0,0 +1,144 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +#ifdef UNFINISHED + +// tqueue.h - template classes for Queue and QItem + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef TQUEUE_H +#define TQUEUE_H + +#define MAX_QUEUE_SIZE 50 + +#include "osdep.h" // MUTEX_T, etc + +// Forward declarations. +template class Queue; + +// Template for Queue. +template +class Queue { + private: + // private copy/assign constructors: + Queue(const Queue &src); + void operator=(const Queue &src); + protected: + // structs: + class QItem { + private: + // private copy/assign constructors: + QItem(const QItem &src); + void operator=(const QItem &src); + public: + qdata_t *data; + QItem *next; + QItem(void) :data(NULL), next(NULL) { }; + QItem(qdata_t *dnew) :data(dnew), next(NULL) { }; + }; + // data: + int size; + int max_size; + QItem *front; + QItem *end; + MUTEX_T mx_queue; + COND_T cv_push; + COND_T cv_pop; + //functions + int MXlock(void) { return(MUTEX_LOCK(&mx_queue)); }; + int MXunlock(void) { return(MUTEX_UNLOCK(&mx_queue)); }; + public: + // constructor: + Queue(void); + Queue(int qmaxsize); + // functions: + void push(qdata_t *qadd); + qdata_t* pop(void); +}; + + +///// Template Queue: + +// Queue constructor (default). +template Queue::Queue(void) + : size(0), max_size(MAX_QUEUE_SIZE), front(NULL), end(NULL), mx_queue(), + cv_push(), cv_pop() +{ + MUTEX_INIT(&mx_queue); + COND_INIT(&cv_push); + COND_INIT(&cv_pop); +} + +// Queue constructor. +template Queue::Queue(int qmaxsize) + : size(0), max_size(qmaxsize), front(NULL), end(NULL), mx_queue(), + cv_push(), cv_pop() +{ + MUTEX_INIT(&mx_queue); + COND_INIT(&cv_push); + COND_INIT(&cv_pop); +} + +// Push onto the queue (at end). +template void Queue::push(qdata_t *qadd) { + QItem *qnew; + MXlock(); + while(size >= max_size) + COND_WAIT(&cv_push, &mx_queue); + qnew = new QItem(qadd); + end->next = qnew; + end=qnew; + size++; + MXunlock(); +} + +// Pop from queue (from front). Wait for an item to actually be available +// on the queue (block until there's something there). +template qdata_t* Queue::pop(void) { + QItem *qtmp; + qdata_t *ret; + MXlock(); + while(!size) + COND_WAIT(&cv_pop, &mx_queue); + qtmp=front; + front=qtmp->next; + size--; + ret=qtmp->data; + delete qtmp; + MXunlock(); + return(ret); +} + +#endif /* TQUEUE_H */ + +#endif /* UNFINISHED */ diff --git a/sdk/metamod/types_meta.h b/sdk/metamod/types_meta.h new file mode 100644 index 0000000..01b14f7 --- /dev/null +++ b/sdk/metamod/types_meta.h @@ -0,0 +1,82 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// types_meta.h - common internal type, etc definitions + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef TYPES_META_H +#define TYPES_META_H + +// Our own boolean type, for stricter type matching. +typedef enum mBOOL { + mFALSE = 0, + mTRUE, +} mBOOL; + +// Like C's errno, for our various functions; describes causes of failure +// or mFALSE returns. +typedef enum { + ME_NOERROR = 0, + ME_FORMAT, // invalid format + ME_COMMENT, // ignored comment + ME_BLANK, // ignored blank (empty) line + ME_ALREADY, // request had already been done + ME_DELAYED, // request is delayed + ME_NOTALLOWED, // request not allowed + ME_SKIPPED, // request is being skipped for whatever reason + ME_BADREQ, // invalid request for this + ME_ARGUMENT, // invalid arguments + ME_NULLRESULT, // resulting data was empty or null + ME_MAXREACHED, // reached max/limit + ME_NOTUNIQ, // not unique (ambigious match) + ME_NOTFOUND, // in find operation, match not found + ME_NOFILE, // file empty or missing + ME_NOMEM, // malloc failed + ME_BADMEMPTR, // invalid memory address + ME_OSNOTSUP, // OS doesn't support this operation + ME_DLOPEN, // failed to open shared lib/dll + ME_DLMISSING, // symbol missing in lib/dll + ME_DLERROR, // some other error encountered calling functions from dll + ME_IFVERSION, // incompatible interface version + ME_UNLOAD_UNLOADER, // tried to unload unloader + ME_UNLOAD_SELF, // tried to unload self +} META_ERRNO; +extern META_ERRNO meta_errno; + +#define RETURN_ERRNO(retval, errval) \ + do { meta_errno=errval; return(retval); } while(0) + +#define RETURN_LOGERR_ERRNO(errargs, retval, errval) \ + do { META_ERROR errargs ; meta_errno=errval; return(retval); } while(0) + +#endif /* TYPES_META_H */ diff --git a/sdk/metamod/vdate.h b/sdk/metamod/vdate.h new file mode 100644 index 0000000..b35c0a0 --- /dev/null +++ b/sdk/metamod/vdate.h @@ -0,0 +1,44 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// vdate.h - compile-time version date + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef VDATE_H +#define VDATE_H + +extern char const *COMPILE_TIME; + +extern char const *COMPILE_TZONE; + +#endif /* VDATE_H */ diff --git a/sdk/metamod/vers_meta.h b/sdk/metamod/vers_meta.h new file mode 100644 index 0000000..28efed6 --- /dev/null +++ b/sdk/metamod/vers_meta.h @@ -0,0 +1,55 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// vers_meta.h - version info, intended to be common among DLLs distributed +// with metamod. + +/* + * Copyright (c) 2001-2005 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef VERS_META_H +#define VERS_META_H + +#ifndef OPT_TYPE +# if defined(_MSC_VER) && defined(_DEBUG) +# define OPT_TYPE "msc debugging" +# elif defined(_MSC_VER) && defined(NDEBUG) +# define OPT_TYPE "msc optimized" +# else +# define OPT_TYPE "default" +# endif /* _MSC_VER */ +#endif /* not OPT_TYPE */ + +#define VDATE "2006-04-17" +#define VVERSION "1.19" +#define RC_VERS_DWORD 1,19,0,0 // Version Windows DLL Resources in res_meta.rc + +#endif /* VERS_META_H */