diff --git a/.gitignore b/.gitignore index b71e00a9..5c7121c7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,14 @@ *~ +darkstar/ +hunger/ +noffice/ +pvk/ +ship/ +src/client/cstrike.new +src/server/cstrike.new +src/shared/cstrike.new *.lno +*.pk3 csqccore.txt ssqccore.txt menucore.txt diff --git a/gearbox/data.pk3dir/particles/shockrifle.cfg b/gearbox/data.pk3dir/particles/shockrifle.cfg new file mode 100755 index 00000000..b8f93f4f --- /dev/null +++ b/gearbox/data.pk3dir/particles/shockrifle.cfg @@ -0,0 +1,17 @@ +r_part shockrifle_piece +{ + type texturedspark + texture ball + tcoords 1 65 31 95 256 8 32 + scale 1 + count 8 + scalefactor 1 + alpha 0.5 + die 25 + rgb 0 255 255 + blend add + spawnmode ball + spawnorg 1 + friction 0.5 + gravity 0 +} diff --git a/logos/README b/logos/README new file mode 100644 index 00000000..80544a1f --- /dev/null +++ b/logos/README @@ -0,0 +1,2 @@ +Put your sprays/graffiti here. +The dimensions/format doesn't matter, as long as it fits under 8 kB. diff --git a/logos/fte.png b/logos/fte.png new file mode 100644 index 00000000..7fa5105d Binary files /dev/null and b/logos/fte.png differ diff --git a/poke646/data.pk3dir/default.cfg b/poke646/data.pk3dir/default.cfg new file mode 100755 index 00000000..ea644e9a --- /dev/null +++ b/poke646/data.pk3dir/default.cfg @@ -0,0 +1,87 @@ +// Generic Binds +bind "ESC" "togglemenu" +bind "w" "+forward" +bind "s" "+back" +bind "a" "+moveleft" +bind "d" "+moveright" +bind "SPACE" "+jump" +bind "CTRL" "+duck" +bind "SHIFT" "+speed" +bind "0" "slot10" +bind "1" "slot1" +bind "2" "slot2" +bind "3" "slot3" +bind "4" "slot4" +bind "5" "slot5" +bind "6" "slot6" +bind "7" "slot7" +bind "8" "slot8" +bind "9" "slot9" +bind "UPARROW" "+forward" +bind "DOWNARROW" "+back" +bind "LEFTARROW" "+left" +bind "RIGHTARROW" "+right" +bind "MOUSE1" "+attack" +bind "MOUSE2" "+attack2" +bind "MWHEELDOWN" "invnext" +bind "MWHEELUP" "invprev" +bind "r" "+reload" +bind "e" "+use" +bind "TAB" "+showscores" +bind "y" "messagemode" +bind "u" "messagemode2" +bind "t" "impulse 201" +bind "f" "impulse 100" + +// Physics Variables +serverinfo "phy_stepheight" "18" +serverinfo "phy_airstepheight" "18" +serverinfo "phy_friction" "4" +serverinfo "phy_edgefriction" "1" +serverinfo "phy_stopspeed" "75" +serverinfo "phy_gravity" "800" +serverinfo "phy_airaccelerate" "10" +serverinfo "phy_accelerate" "8" +serverinfo "phy_maxspeed" "270" + +// 2D/HUD Variables +seta "con_color" "193 207 204" +seta "vgui_color" "0 255 0" +seta "cross_color" "0 255 0" +seta "vid_conautoscale" "1" +seta "con_textsize" "12" +seta "cl_cursor_scale" "1" +seta "vid_conautoscale" "1" +seta "scr_conalpha" "1" + +// View Variables +seta "cl_bob" "0" +seta "maxpitch" "89" +seta "minpitch" "-89" +seta "r_meshpitch" "1" +seta "v_bob" "0.01" +seta "v_bobcycle" "0.8" +seta "v_bobup" "0.5" +seta "v_contentblend" "0" + +// 3D World Variables +seta "gl_blacklist_debug_glsl" "0" +seta "gl_overbright" "0" +seta "r_fb_models" "0" +seta "r_fullbrightSkins" "0" +seta "r_particledesc" "default" +seta "r_polygonoffset_submodel_factor" "0" +seta "r_polygonoffset_submodel_offset" "0" +seta "r_shadow_realtime_dlight_shadows" "0" +seta "r_shadow_realtime_world_shadows" "0" + +// Misc defaults +seta "cfg_save_auto" "1" +seta "cl_idlefps" "60" +seta "cl_maxfps" "250" +seta "com_nogamedirnativecode" "0" +seta "con_logcenterprint" "0" +seta "con_notifylines" "0" +seta "lang" "en_us" +seta "r_imageexensions" "tga bmp pcx" +seta "scr_sshot_type" "tga" diff --git a/poke646/modinfo.txt b/poke646/modinfo.txt new file mode 100644 index 00000000..86af5442 --- /dev/null +++ b/poke646/modinfo.txt @@ -0,0 +1,11 @@ +game "Poke646" +url_info "www.poke646.com" +url_dl "" +version "1.0" +startmap "po_intro" +trainmap "po_haz01" +type "singleplayer_only" +svonly "0" +cldll "1" +nomodels "0" +size "123055258" diff --git a/src/Makefile b/src/Makefile index c90969bb..5568b67e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,16 +1,17 @@ CC=fteqcc -qc-progs: +all: + make menu + make games + make mods + +menu: $(CC) menu-fn/progs.src + +games: mkdir -p ../valve/data.pk3dir $(CC) client/valve/progs.src $(CC) server/valve/progs.src - mkdir -p ../scihunt/data.pk3dir - $(CC) client/scihunt/progs.src - $(CC) server/scihunt/progs.src - mkdir -p ../cstrike/data.pk3dir - $(CC) client/cstrike/progs.src - $(CC) server/cstrike/progs.src mkdir -p ../rewolf/data.pk3dir $(CC) client/rewolf/progs.src $(CC) server/rewolf/progs.src @@ -20,3 +21,17 @@ qc-progs: mkdir -p ../tfc/data.pk3dir $(CC) client/tfc/progs.src $(CC) server/tfc/progs.src + +mods: + #mkdir -p ../cstrike/data.pk3dir + #$(CC) client/cstrike/progs.src + #$(CC) server/cstrike/progs.src + mkdir -p ../scihunt/data.pk3dir + $(CC) client/scihunt/progs.src + $(CC) server/scihunt/progs.src + mkdir -p ../poke646/data.pk3dir + $(CC) client/poke646/progs.src + $(CC) server/poke646/progs.src + mkdir -p ../hunger/data.pk3dir + $(CC) client/hunger/progs.src + $(CC) server/hunger/progs.src diff --git a/src/client/poke646/entities.c b/src/client/poke646/entities.c new file mode 100644 index 00000000..8cb88cd7 --- /dev/null +++ b/src/client/poke646/entities.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +int +Game_Entity_Update(float id, float new) +{ + switch (id) { + default: + return FALSE; + } + + return TRUE; +} diff --git a/src/client/poke646/init.c b/src/client/poke646/init.c new file mode 100644 index 00000000..534aba49 --- /dev/null +++ b/src/client/poke646/init.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +float(entity foo, float chanid) getchannellevel = #0; + + +/* +================= +Client_Init + +Comparable to worldspawn in SSQC in that it's mostly used for precaches +================= +*/ +void Client_Init(float apilevel, string enginename, float engineversion) +{ + precache_model("sprites/640hud1.spr"); + precache_model("sprites/640hud2.spr"); + precache_model("sprites/640hud3.spr"); + precache_model("sprites/640hud4.spr"); + precache_model("sprites/640hud5.spr"); + precache_model("sprites/640hud6.spr"); + precache_model("sprites/hud640_01.spr"); + precache_model("sprites/hud640_02.spr"); + precache_model("sprites/hud640_04.spr"); + + BEAM_TRIPMINE = particleeffectnum("beam_tripmine"); +} + +void Client_InitDone(void) +{ +} + +void Game_RendererRestarted(string rstr) +{ + +} diff --git a/src/client/poke646/progs.src b/src/client/poke646/progs.src new file mode 100644 index 00000000..db55f406 --- /dev/null +++ b/src/client/poke646/progs.src @@ -0,0 +1,72 @@ +#pragma target fte +#pragma progs_dat "../../../poke646/data.pk3dir/csprogs.dat" + +#define CSQC +#define VALVE +#define POKE646 + +#includelist +../../shared/fteextensions.qc +../../shared/defs.h +../../shared/math.h +../../shared/materials.h +../../shared/events.h +../../shared/entities.h +../valve/defs.h +../valve/particles.h +../defs.h +../../vgui/include.src +../util.c +../sky.c +../fade.c +../sprite.cpp +../titles.c +../text.c +../sentences.c + +../../gs-entbase/client.src +../sound.c +../prints.c +../voice.c +../../shared/valve/animations.h +../../shared/valve/animations.c +../../shared/valve/player.cpp +../player.c +../../shared/pmove.c +../predict.c +../../shared/decals.c +../../shared/effects.c +../../shared/spraylogo.cpp +../npc.c +init.c +../../shared/poke646/items.h +../../shared/valve/weapon_common.h +../../shared/poke646/weapons.h +../../shared/poke646/w_bradnailer.c +../../shared/poke646/w_cmlwbr.c +../../shared/poke646/w_heaterpipe.c +../../shared/poke646/w_nailgun.c +../../shared/poke646/w_pipebomb.c +../../shared/poke646/w_shotgun.c +../../shared/poke646/w_xs.c +../../shared/poke646/weapons.c +../../shared/valve/weapon_common.c +../valve/player.c +entities.c +../entities.c +../valve/cmds.c +../valve/game_event.c +../events.c +../valve/view.c +../view.c +../damage.c +../obituary.c +../chat.c +../vgui.cpp +../valve/hud.h +../valve/hud.c +../valve/hud_weaponselect.c +../valve/scoreboard.c +../valve/input.c +../entry.c +#endlist diff --git a/src/client/valve/hud.h b/src/client/valve/hud.h new file mode 100644 index 00000000..6ca6ca76 --- /dev/null +++ b/src/client/valve/hud.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* pre-calculated sprite definitions */ +float spr_health[4] = { + 80 / 256, // pos x + 24 / 128, // pos u + 32 / 256, // size x + 32 / 128 // size y +}; + +float spr_suit1[4] = { + 0 / 256, // pos x + 24 / 128, // pos u + 40 / 256, // size x + 40 / 128 // size y +}; + +float spr_suit2[4] = { + 40 / 256, // pos x + 24 / 128, // pos u + 40 / 256, // size x + 40 / 128 // size y +}; + +float spr_flash1[4] = { + 160 / 256, // pos x + 24 / 128, // pos u + 32 / 256, // size x + 32 / 128 // size y +}; + +float spr_flash2[4] = { + 112 / 256, // pos x + 24 / 128, // pos u + 48 / 256, // size x + 32 / 128 // size y +}; diff --git a/src/gs-entbase/client/env_sound.cpp b/src/gs-entbase/client/env_sound.cpp index f0b0253c..604b2ebf 100644 --- a/src/gs-entbase/client/env_sound.cpp +++ b/src/gs-entbase/client/env_sound.cpp @@ -14,6 +14,9 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/* this is causing crashes on OpenAL 1.19.1 when enabled */ +//#define DSP_LERP + /*QUAKED env_sound (1 0 0) (-8 -8 -8) (8 8 8) "radius" Radius in units. "roomtype" Roomtype value: @@ -276,7 +279,6 @@ void DSP_SetEnvironment(int id) g_iDSPold = g_iDSP; g_iDSP = id; g_flDSPTime = 0.0f; - print(sprintf("Environment changed to %i.\n", g_iDSP)); } reverbinfo_t mix; @@ -314,6 +316,8 @@ void DSP_Interpolate(int id) var int autocvar_dsp_environments = TRUE; void DSP_UpdateListener(void) { + static int old_dsp; + vector vecPlayer; if (autocvar_dsp_environments == FALSE) { @@ -351,14 +355,27 @@ void DSP_UpdateListener(void) DSP_SetEnvironment(scape.m_iRoomType); } - if (g_flDSPTime < 1.0) { - DSP_Interpolate(g_iDSP); - setup_reverb(12, &mix, sizeof(reverbinfo_t)); - } - makevectors(getproperty(VF_CL_VIEWANGLES)); SetListener(getproperty(VF_ORIGIN), v_forward, v_right, v_up, 12); + + if (old_dsp == g_iDSP) { + return; + } + +#ifdef DSP_LERP + if (g_flDSPTime < 1.0) + { + DSP_Interpolate(g_iDSP); + setup_reverb(12, &mix, sizeof(reverbinfo_t)); + } else { + old_dsp = g_iDSP; + } g_flDSPTime += clframetime; +#else + print(sprintf("[DSP] Environment changed to %i.\n", g_iDSP)); + old_dsp = g_iDSP; + setup_reverb(12, &reverbPresets[g_iDSP], sizeof(reverbinfo_t)); +#endif } void DSP_Init(void) diff --git a/src/gs-entbase/client/prop_rope.cpp b/src/gs-entbase/client/prop_rope.cpp index 4c175252..93ad66bd 100644 --- a/src/gs-entbase/client/prop_rope.cpp +++ b/src/gs-entbase/client/prop_rope.cpp @@ -14,6 +14,10 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define ROPE_RIBBON + +void(float radius, vector texcoordbias) R_EndPolygonRibbon = #0; + var int autocvar_rope_debug = FALSE; class prop_rope:CBaseEntity @@ -24,10 +28,14 @@ class prop_rope:CBaseEntity void() prop_rope; virtual float() predraw; - virtual void(vector, vector, int) draw_segment; virtual void(string, string) SpawnKey; + +#ifndef ROPE_RIBBON + virtual void(vector, vector, int) draw_segment; +#endif }; +#ifndef ROPE_RIBBON void prop_rope::draw_segment(vector start, vector end, int flip) { vector fsize = [2,2]; @@ -77,6 +85,7 @@ void prop_rope::draw_segment(vector start, vector end, int flip) R_EndPolygon(); } } +#endif float prop_rope::predraw(void) { @@ -121,7 +130,16 @@ float prop_rope::predraw(void) /* travel further and sag */ pos2 = pos1 + (v_forward * travel) + (v_up * -sag) + ((v_right * sin(time)) * m_flSwingFactor); +#ifndef ROPE_RIBBON draw_segment(pos1, pos2, 0); +#else + vector lit1 = /*[0.1,0.1,0.1] */ getlight(pos1) / 255; + vector lit2 = /*[0.1,0.1,0.1] */ getlight(pos2) / 255; + R_BeginPolygon(m_strShader, 0, 0); + R_PolygonVertex(pos1, [0,0], lit1, 1.0f); + R_PolygonVertex(pos2, [0,1], lit2, 1.0f); + R_EndPolygonRibbon(2, [1,0]); +#endif pos1 = pos2; sc += (M_PI * (1 / segments)); @@ -138,7 +156,17 @@ float prop_rope::predraw(void) /* travel further and sag */ pos2 = pos1 + (v_forward * travel) + (v_up * -sag) - ((v_right * sin(time)) * m_flSwingFactor); - draw_segment(pos1, pos2, 1); +#ifndef ROPE_RIBBON + draw_segment(pos1, pos2, 0); +#else + vector lit1 = /*[0.1,0.1,0.1] */ getlight(pos1) / 255; + vector lit2 = /*[0.1,0.1,0.1] */ getlight(pos2) / 255; + + R_BeginPolygon(m_strShader, 0, 0); + R_PolygonVertex(pos1, [0,0], lit1, 1.0f); + R_PolygonVertex(pos2, [0,1], lit2, 1.0f); + R_EndPolygonRibbon(2, [-1,0]); +#endif pos1 = pos2; sc += (M_PI * (1 / segments)); diff --git a/src/gs-entbase/client/worldspawn.cpp b/src/gs-entbase/client/worldspawn.cpp index 7d2e9289..c512a107 100644 --- a/src/gs-entbase/client/worldspawn.cpp +++ b/src/gs-entbase/client/worldspawn.cpp @@ -32,6 +32,9 @@ void worldspawn::Initialized(void) void worldspawn::SpawnKey(string strField, string strKey) { switch (strField) { + case "sun_pos": + g_vecSunDir = stov(strKey); + break; case "skyname": Sky_Set(strKey); break; diff --git a/src/gs-entbase/server/ambient_generic.cpp b/src/gs-entbase/server/ambient_generic.cpp index 9794e58a..5595726c 100644 --- a/src/gs-entbase/server/ambient_generic.cpp +++ b/src/gs-entbase/server/ambient_generic.cpp @@ -14,7 +14,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/*QUAKED ambient_generic (1 0 0) (-8 -8 -8) (8 8 8) AS_SRADIUS AS_MRADIUS AS_LRADIUS AS_SILENT AS_NOTTOGGLED +/*QUAKED ambient_generic (1 0 0) (-8 -8 -8) (8 8 8) AS_ARADIUS AS_SRADIUS AS_MRADIUS AS_LRADIUS AS_SILENT AS_NOTTOGGLED "targetname" Name "target" Target when triggered. "killtarget" Target to kill when triggered. diff --git a/src/gs-entbase/server/baseentity.cpp b/src/gs-entbase/server/baseentity.cpp index aac682ba..7e2b03c3 100644 --- a/src/gs-entbase/server/baseentity.cpp +++ b/src/gs-entbase/server/baseentity.cpp @@ -26,6 +26,8 @@ enum class CBaseEntity { + string m_strTarget; + string m_strTargetName; string m_oldModel; float m_oldSolid; float m_oldHealth; @@ -41,8 +43,24 @@ class CBaseEntity virtual void() Respawn; virtual void() Hide; virtual void() RendermodeUpdate; + virtual void() ParentUpdate; }; +/* Make sure StartFrame calls this */ +void CBaseEntity::ParentUpdate(void) +{ + if (m_parent) { + entity p = find(world, CBaseEntity::m_strTargetName, m_parent); + + if (!p) { + return; + } + + setorigin(this, p.origin); + nextthink = time; + } +} + void CBaseEntity :: CBaseEntity ( void ) { /* Not in Deathmatch */ @@ -64,10 +82,19 @@ void CBaseEntity :: CBaseEntity ( void ) m_oldHealth = health; m_oldOrigin = origin; m_oldAngle = angles; + effects |= EF_NOSHADOW; int nfields = tokenize( __fullspawndata ); for ( int i = 1; i < ( nfields - 1 ); i += 2 ) { switch ( argv( i ) ) { + case "targetname": + m_strTargetName = argv( i + 1 ); + targetname = __NULL__; + break; + case "target": + m_strTarget = argv( i + 1 ); + target = __NULL__; + break; case "renderamt": m_renderamt = stof( argv( i + 1 ) ); break; @@ -77,6 +104,9 @@ void CBaseEntity :: CBaseEntity ( void ) case "rendermode": m_rendermode = stof( argv( i + 1 ) ); break; + case "parentname": + m_parent = argv(i+1); + break; default: break; } diff --git a/src/gs-entbase/server/basephysics.cpp b/src/gs-entbase/server/basephysics.cpp index 114562cc..95c1141e 100644 --- a/src/gs-entbase/server/basephysics.cpp +++ b/src/gs-entbase/server/basephysics.cpp @@ -12,13 +12,47 @@ class CBasePhysics:CBaseEntity { int m_iShape; int m_iMaterial; + float m_flMass; void() CBasePhysics; virtual void() Respawn; virtual void() touch; + virtual void() TouchThink; virtual void(entity, int, int) vPain; }; +void CBasePhysics::TouchThink(void) +{ +#ifdef GS_BULLET_PHYSICS + /* let players collide */ + dimension_solid = 255; + dimension_hit = 255; + + tracebox(origin, mins, maxs, origin, FALSE, this); + + /* stuck */ + if (trace_startsolid) { + if (trace_ent.flags & FL_CLIENT) { + physics_enable(this, TRUE); + makevectors(vectoangles(origin - trace_ent.origin)); + velocity = v_forward * 256; + } + } + + /* If we barely move, disable the physics simulator */ + if (vlen(velocity) <= 1) { + physics_enable(this, FALSE); + } + + /* don't let players collide */ + dimension_solid = 1; + dimension_hit = 1; + + /* continue testing next frame */ + nextthink = time; +#endif +} + void CBasePhysics::touch(void) { #ifdef GS_BULLET_PHYSICS @@ -49,6 +83,14 @@ void CBasePhysics::Respawn(void) physics_enable(this, FALSE); takedamage = DAMAGE_YES; health = 100000; + mass = m_flMass; + + /* don't let players collide */ + dimension_solid = 1; + dimension_hit = 1; + + think = TouchThink; + nextthink = time + 0.1f; #else movetype = MOVETYPE_NONE; solid = SOLID_BBOX; @@ -61,6 +103,7 @@ void CBasePhysics::CBasePhysics(void) { CBaseEntity::CBaseEntity(); precache_model(m_oldModel); + m_flMass = 1.0f; for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) { switch (argv(i)) { @@ -71,6 +114,11 @@ void CBasePhysics::CBasePhysics(void) m_iShape = 0; } break; + case "massscale": + m_flMass = stof(argv(i + 1)); + break; + case "physdamagescale": + break; case "material": m_iMaterial = stof(argv(i + 1)); break; @@ -83,4 +131,7 @@ void CBasePhysics::CBasePhysics(void) CLASSEXPORT(prop_physics, CBasePhysics) CLASSEXPORT(prop_physics_multiplayer, CBasePhysics) + +CLASSEXPORT(func_physbox, CBasePhysics) +CLASSEXPORT(func_physbox_multiplayer, CBasePhysics) diff --git a/src/gs-entbase/server/basetrigger.cpp b/src/gs-entbase/server/basetrigger.cpp index dadd26d0..0256fb4e 100644 --- a/src/gs-entbase/server/basetrigger.cpp +++ b/src/gs-entbase/server/basetrigger.cpp @@ -22,8 +22,6 @@ enum { class CBaseTrigger : CBaseEntity { int m_strGlobalState; - string m_strTarget; - string m_strTargetName; string m_strKillTarget; string m_strMessage; string m_strMaster; @@ -37,21 +35,8 @@ class CBaseTrigger : CBaseEntity virtual void( float del ) UseTargets_Delay; virtual void() InitBrushTrigger; virtual void() InitPointTrigger; - virtual void() ParentUpdate; }; -void CBaseTrigger::ParentUpdate(void) -{ - entity p = find(world, CBaseTrigger::m_strTarget, m_parent); - - if (!p) { - return; - } - - setorigin(this, p.origin); - nextthink = time; -} - void CBaseTrigger :: UseTargets ( void ) { for ( entity eFind = world; ( eFind = find( eFind, CBaseTrigger::m_strTargetName, m_strTarget ) ); ) { @@ -143,14 +128,6 @@ void CBaseTrigger :: CBaseTrigger ( void ) { for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) { switch ( argv( i ) ) { - case "target": - m_strTarget = argv( i + 1 ); - target = __NULL__; - break; - case "targetname": - m_strTargetName = argv( i + 1 ); - targetname = __NULL__; - break; case "killtarget": m_strKillTarget = argv( i + 1 ); break; @@ -160,11 +137,6 @@ void CBaseTrigger :: CBaseTrigger ( void ) case "master": m_strMaster = argv(i+1); break; - case "parentname": - m_parent = argv(i+1); - think = ParentUpdate; - nextthink = time; - break; default: break; } diff --git a/src/gs-entbase/server/func_breakable.cpp b/src/gs-entbase/server/func_breakable.cpp index 92ef30ff..a3d07e56 100755 --- a/src/gs-entbase/server/func_breakable.cpp +++ b/src/gs-entbase/server/func_breakable.cpp @@ -248,6 +248,3 @@ void func_breakable::func_breakable(void) } } } - -CLASSEXPORT(func_physbox, func_breakable) -CLASSEXPORT(func_physbox_multiplayer, func_breakable) diff --git a/src/gs-entbase/server/func_door_rotating.cpp b/src/gs-entbase/server/func_door_rotating.cpp index 3a62497e..04882fc7 100644 --- a/src/gs-entbase/server/func_door_rotating.cpp +++ b/src/gs-entbase/server/func_door_rotating.cpp @@ -325,7 +325,7 @@ void func_door_rotating::Respawn(void) if (!m_flDistance) { m_flDistance = 90; } - + #ifdef GS_BULLET_PHYSICS takedamage = DAMAGE_YES; health = 100; @@ -334,8 +334,8 @@ void func_door_rotating::Respawn(void) solid = SOLID_BSP; movetype = MOVETYPE_PUSH; - setorigin(this, m_oldOrigin); setmodel(this, m_oldModel); + setorigin(this, m_oldOrigin); think = __NULL__; nextthink = -1; m_pMove = 0; diff --git a/src/gs-entbase/server/func_physbox_multiplayer.cpp b/src/gs-entbase/server/func_physbox_multiplayer.cpp index f66461c5..9a706db3 100644 --- a/src/gs-entbase/server/func_physbox_multiplayer.cpp +++ b/src/gs-entbase/server/func_physbox_multiplayer.cpp @@ -39,4 +39,5 @@ void func_physbox::func_physbox(void) } } +CLASSEXPORT(func_physbox, func_physbox) CLASSEXPORT(func_physbox_multiplayer, func_physbox) diff --git a/src/gs-entbase/server/multi_manager.cpp b/src/gs-entbase/server/multi_manager.cpp index c55e84f9..6194b724 100644 --- a/src/gs-entbase/server/multi_manager.cpp +++ b/src/gs-entbase/server/multi_manager.cpp @@ -121,6 +121,8 @@ void multi_manager :: multi_manager (void) case "origin": case "targetname": case "spawnflags": + case "angle": + case "angles": continue; break; default: diff --git a/src/server/poke646/ammo_p646.cpp b/src/server/poke646/ammo_p646.cpp new file mode 100644 index 00000000..fb72b0a0 --- /dev/null +++ b/src/server/poke646/ammo_p646.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +class item_ammo:CBaseEntity +{ + void() item_ammo; + virtual void() Respawn; + virtual void() touch; +}; + +void item_ammo::touch(void) +{ + if (other.classname != "player") { + return; + } + + player pl = (player)other; + sound(other, CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM); + Weapons_RefreshAmmo(pl); + Logging_Pickup(other, this, __NULL__); + + if (cvar("sv_playerslots") == 1) { + remove(self); + } else { + Hide(); + think = Respawn; + nextthink = time + 20.0f; + } +} + +void item_ammo::Respawn(void) +{ + solid = SOLID_TRIGGER; + movetype = MOVETYPE_TOSS; + + if (m_oldModel) { + setmodel(this, m_oldModel); + } + + setsize(this, [-16,-16,0], [16,16,16]); + setorigin(this, origin); + + think = __NULL__; + nextthink = -1; + sound(this, CHAN_ITEM, "items/suitchargeok1.wav", 1, ATTN_NORM, 150); + droptofloor(); +} + +void item_ammo::item_ammo(void) +{ + m_oldModel = model; + setmodel(this, m_oldModel); + CBaseEntity::CBaseEntity(); + item_ammo::Respawn(); +} + +/* + * Ammo for the Crossbow. + * A single ammo_bolts will provide 5 bolts. + */ + +class +ammo_bolts:item_ammo +{ + void() ammo_bolts; +}; + +void +ammo_bolts::ammo_bolts(void) +{ + model = "models/w_crossbow_clip.mdl"; +} + +/* + * Ammo for the nailguns. + * A single ammo_nailclip will provide 25 nails. + */ + +class +ammo_nailclip:item_ammo +{ + void() ammo_nailclip; +}; + +void +ammo_nailclip::ammo_nailclip(void) +{ + model = "models/w_nailclip.mdl"; +} + +/* + * Ammo for the Nailgun. + * A single ammo_nailround will provide 50 nails. + */ + +class +ammo_nailround:item_ammo +{ + void() ammo_nailround; +}; + +void +ammo_nailround::ammo_nailround(void) +{ + model = "models/w_nailround.mdl"; +} + +/* + * Ammo for the alien. + * A single ammo_xencandy will provide 20 snacks. + */ + +class +ammo_xencandy:item_ammo +{ + void() ammo_xencandy; +}; + +void +ammo_xencandy::ammo_xencandy(void) +{ + model = "models/w_xencandy.mdl"; +} diff --git a/src/server/poke646/client.c b/src/server/poke646/client.c new file mode 100644 index 00000000..f2c03d1a --- /dev/null +++ b/src/server/poke646/client.c @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +var int autocvar_sv_networkeverything = FALSE; + +void weaponbox_spawn(player temp) +{ + +} + +void +Game_ClientConnect(void) +{ + entity a; + bprint(PRINT_HIGH, sprintf("%s connected\n", self.netname)); + + int playercount = 0; + for (a = world; (a = find(a, classname, "player"));) { + playercount++; + } + + /* we're the first. respawn all entities? */ + if (playercount == 0) { + for (a = world; (a = findfloat(a, gflags, GF_CANRESPAWN));) { + CBaseEntity caw = (CBaseEntity)a; + caw.Respawn(); + } + } +} + +void +Game_ClientDisconnect(void) +{ + bprint(PRINT_HIGH, sprintf("%s disconnected\n", self.netname)); + + /* Make this unusable */ + self.solid = SOLID_NOT; + self.movetype = MOVETYPE_NONE; + self.modelindex = 0; + self.health = 0; + self.takedamage = 0; + self.SendFlags = PLAYER_MODELINDEX; +} + +void +Game_ClientKill(void) +{ + Damage_Apply(self, self, self.health, WEAPON_NONE, DMG_SKIP_ARMOR); +} + +void +Game_PlayerPreThink(void) +{ + +} + +void +Game_PlayerPostThink(void) +{ + player pl = (player)self; + Animation_PlayerUpdate(); + + pl.SendFlags |= PLAYER_KEEPALIVE; + + if (pl.old_modelindex != pl.modelindex) { + pl.SendFlags |= PLAYER_MODELINDEX; + } + if (pl.old_origin[0] != pl.origin[0]) { + pl.SendFlags |= PLAYER_ORIGIN; + } + if (pl.old_origin[1] != pl.origin[1]) { + pl.SendFlags |= PLAYER_ORIGIN; + } + if (pl.old_origin[2] != pl.origin[2]) { + pl.SendFlags |= PLAYER_ORIGIN_Z; + } + if (pl.old_angles[0] != pl.angles[0]) { + pl.SendFlags |= PLAYER_ANGLES_X; + } + if (pl.old_angles[1] != pl.angles[1]) { + pl.SendFlags |= PLAYER_ANGLES_Y; + } + if (pl.old_angles[2] != pl.angles[2]) { + pl.SendFlags |= PLAYER_ANGLES_Z; + } + if (pl.old_velocity[0] != pl.velocity[0]) { + pl.SendFlags |= PLAYER_VELOCITY; + } + if (pl.old_velocity[1] != pl.velocity[1]) { + pl.SendFlags |= PLAYER_VELOCITY; + } + if (pl.old_velocity[2] != pl.velocity[2]) { + pl.SendFlags |= PLAYER_VELOCITY_Z; + } + if (pl.old_flags != pl.flags) { + pl.SendFlags |= PLAYER_FLAGS; + } + if (pl.old_activeweapon != pl.activeweapon) { + pl.SendFlags |= PLAYER_WEAPON; + } + if (pl.old_items != pl.g_items) { + pl.SendFlags |= PLAYER_ITEMS; + } + if (pl.old_health != pl.health) { + pl.SendFlags |= PLAYER_HEALTH; + } + if (pl.old_armor != pl.armor) { + pl.SendFlags |= PLAYER_ARMOR; + } + if (pl.old_movetype != pl.movetype) { + pl.SendFlags |= PLAYER_MOVETYPE; + } + if (pl.old_viewofs != pl.view_ofs[2]) { + pl.SendFlags |= PLAYER_VIEWOFS; + } + if (pl.old_baseframe != pl.baseframe) { + pl.SendFlags |= PLAYER_BASEFRAME; + } + if (pl.old_frame != pl.frame) { + pl.SendFlags |= PLAYER_FRAME; + } + if (pl.old_a_ammo1 != pl.a_ammo1) { + pl.SendFlags |= PLAYER_AMMO1; + } + if (pl.old_a_ammo2 != pl.a_ammo2) { + pl.SendFlags |= PLAYER_AMMO2; + } + if (pl.old_a_ammo3 != pl.a_ammo3) { + pl.SendFlags |= PLAYER_AMMO3; + } + + pl.old_modelindex = pl.modelindex; + pl.old_origin = pl.origin; + pl.old_angles = pl.angles; + pl.old_velocity = pl.velocity; + pl.old_flags = pl.flags; + pl.old_activeweapon = pl.activeweapon; + pl.old_items = pl.g_items; + pl.old_health = pl.health; + pl.old_armor = pl.armor; + pl.old_movetype = pl.movetype; + pl.old_viewofs = pl.view_ofs[2]; + pl.old_baseframe = pl.baseframe; + pl.old_frame = pl.frame; + pl.old_a_ammo1 = pl.a_ammo1; + pl.old_a_ammo2 = pl.a_ammo2; + pl.old_a_ammo3 = pl.a_ammo3; +} +void +Game_RunClientCommand(void) +{ + Footsteps_Update(); + QPhysics_Run(self); +} + +void +Game_DecodeChangeParms(void) +{ + player pl = (player)self; + g_landmarkpos[0] = parm1; + g_landmarkpos[1] = parm2; + g_landmarkpos[2] = parm3; + pl.angles[0] = parm4; + pl.angles[1] = parm5; + pl.angles[2] = parm6; + pl.velocity[0] = parm7; + pl.velocity[1] = parm8; + pl.velocity[2] = parm9; + pl.g_items = parm10; + pl.activeweapon = parm11; +} + +void +Game_SetChangeParms(void) +{ + player pl = (player)self; + parm1 = g_landmarkpos[0]; + parm2 = g_landmarkpos[1]; + parm3 = g_landmarkpos[2]; + parm4 = pl.angles[0]; + parm5 = pl.angles[1]; + parm6 = pl.angles[2]; + parm7 = pl.velocity[0]; + parm8 = pl.velocity[1]; + parm9 = pl.velocity[2]; + parm10 = pl.g_items; + parm11 = pl.activeweapon; +} + +void +Game_PutClientInServer(void) +{ + if (self.classname != "player") { + spawnfunc_player(); + } + player pl = (player)self; + + entity spot; + pl.classname = "player"; + pl.health = self.max_health = 100; + + pl.takedamage = DAMAGE_YES; + pl.solid = SOLID_SLIDEBOX; + pl.movetype = MOVETYPE_WALK; + pl.flags = FL_CLIENT; + pl.viewzoom = 1.0; + pl.model = "models/player.mdl"; + + string mymodel = infokey(pl, "model"); + + if (mymodel) { + mymodel = sprintf("models/player/%s/%s.mdl", mymodel, mymodel); + if (whichpack(mymodel)) { + pl.model = mymodel; + } + } + setmodel(pl, pl.model); + + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + pl.view_ofs = VEC_PLAYER_VIEWPOS; + pl.velocity = [0,0,0]; + pl.gravity = __NULL__; + pl.frame = 1; + pl.SendEntity = Player_SendEntity; + pl.SendFlags = UPDATE_ALL; + + pl.customphysics = Empty; + pl.vPain = Player_Pain; + pl.vDeath = Player_Death; + pl.iBleeds = TRUE; + forceinfokey(pl, "*spec", "0"); + forceinfokey(self, "*deaths", ftos(self.deaths)); + + if (cvar("sv_playerslots") == 1) { + Game_DecodeChangeParms(); + + if (startspot != "") { + setorigin(pl, Landmark_GetSpot()); + } else { + spot = find(world, classname, "info_player_start"); + setorigin(pl, spot.origin); + pl.angles = spot.angles; + pl.fixangle = TRUE; + } + } else { + spot = Spawn_SelectRandom("info_player_deathmatch"); + setorigin(pl, spot.origin); + pl.angles = spot.angles; + pl.fixangle = TRUE; + pl.g_items |= ITEM_SUIT; + } +} + +void +SV_SendChat(entity sender, string msg, entity eEnt, float fType) +{ + WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); + WriteByte(MSG_MULTICAST, fType == 0 ? EV_CHAT:EV_CHAT_TEAM); + WriteByte(MSG_MULTICAST, num_for_edict(sender) - 1); + WriteByte(MSG_MULTICAST, sender.team); + WriteString(MSG_MULTICAST, msg); + if (eEnt) { + msg_entity = eEnt; + multicast([0,0,0], MULTICAST_ONE); + } else { + multicast([0,0,0], MULTICAST_ALL); + } + + localcmd(sprintf("echo [SERVER] %s: %s\n", sender.netname, msg)); +} + +void +Game_ParseClientCommand(string cmd) +{ + tokenize(cmd); + + if (argv(1) == "timeleft") { + string msg; + string timestring; + float timeleft; + timeleft = cvar("mp_timelimit") - (time / 60); + timestring = Vox_TimeToString(timeleft); + msg = sprintf("we have %s minutes remaining", timestring); + Vox_Singlecast(self, msg); + return; + } + + if (argv(0) == "say") { + SV_SendChat(self, argv(1), world, 0); + return; + } else if (argv(0) == "say_team") { + entity a; + for (a = world; (a = find(a, classname, "player"));) { + if (a.team == self.team) { + SV_SendChat(self, argv(1), a, 1); + } + } + return; + } + + clientcommand(self, cmd); +} + +void +Game_SetNewParms(void) +{ + +} diff --git a/src/server/poke646/input.c b/src/server/poke646/input.c new file mode 100644 index 00000000..7df7e53c --- /dev/null +++ b/src/server/poke646/input.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void +Game_Input(void) +{ + if (input_buttons & INPUT_BUTTON0) { + Weapons_Primary(); + } else if (input_buttons & INPUT_BUTTON4) { + Weapons_Reload(); + } else if (input_buttons & INPUT_BUTTON3) { + Weapons_Secondary(); + } else { + Weapons_Release(); + } + + if (input_buttons & INPUT_BUTTON5) { + Player_UseDown(); + } else { + Player_UseUp(); + } + + if (self.impulse == 100) { + Flashlight_Toggle(); + } + + if (cvar("sv_cheats") == 1) { + player pl = (player)self; + if (self.impulse == 101) { + pl.health = 100; + pl.armor = 100; + Weapons_AddItem(pl, WEAPON_HEATERPIPE); + Weapons_AddItem(pl, WEAPON_BRADNAILER); + Weapons_AddItem(pl, WEAPON_NAILGUN); + Weapons_AddItem(pl, WEAPON_SHOTGUN); + Weapons_AddItem(pl, WEAPON_CMLWBR); + Weapons_AddItem(pl, WEAPON_XS); + Weapons_AddItem(pl, WEAPON_PIPEBOMB); + } + + if (self.impulse == 102) { + // Respawn all the entities + for (entity a = world; (a = findfloat(a, gflags, GF_CANRESPAWN));) { + CBaseEntity caw = (CBaseEntity)a; + caw.Respawn(); + } + bprint(PRINT_HIGH, "Respawning all map entities...\n"); + } + } + + self.impulse = 0; +} diff --git a/src/server/poke646/progs.src b/src/server/poke646/progs.src new file mode 100755 index 00000000..3403c35e --- /dev/null +++ b/src/server/poke646/progs.src @@ -0,0 +1,71 @@ +#pragma target fte +#pragma progs_dat "../../../poke646/data.pk3dir/progs.dat" + +#define QWSSQC +#define VALVE +#define POKE646 + +#includelist +../../shared/fteextensions.qc +../../shared/defs.h +../valve/defs.h +../../shared/math.h +../../shared/materials.h +../../shared/events.h +../../shared/entities.h +../../shared/valve/animations.h +../defs.h +../plugins.c +../logging.c +../nodes.c +../../gs-entbase/server.src +../valve/monster_rat.cpp +../valve/monster_scientist.cpp +../valve/monster_scientist_dead.cpp +../../shared/decals.c +../../shared/effects.c +../../shared/spraylogo.cpp +../../shared/valve/player.cpp +../valve/player.c +../../shared/pmove.c +../valve/spectator.c +../../shared/poke646/items.h +../../shared/valve/weapon_common.h +../../shared/poke646/weapons.h +../../shared/poke646/w_bradnailer.c +../../shared/poke646/w_cmlwbr.c +../../shared/poke646/w_heaterpipe.c +../../shared/poke646/w_nailgun.c +../../shared/poke646/w_pipebomb.c +../../shared/poke646/w_shotgun.c +../../shared/poke646/w_xs.c +../valve/items.cpp +../valve/item_longjump.cpp +../valve/item_suit.cpp +../valve/item_healthkit.cpp +../valve/item_battery.cpp +../valve/world_items.cpp +../valve/xen_spore_small.cpp +../valve/xen_spore_medium.cpp +../valve/xen_spore_large.cpp +../valve/xen_hair.cpp +../valve/xen_plantlight.cpp + +../poke646/ammo_p646.cpp +../../shared/poke646/weapons.c +../../shared/valve/weapon_common.c +../spawn.c +../vox.c +../../shared/valve/animations.c +client.c +../client.c +../valve/server.c +../server.c +../valve/damage.c +../traceattack.c +../footsteps.c +../flashlight.c +input.c +../valve/spawn.c +../entry.c +#endlist diff --git a/src/server/scihunt/monster_scientist.cpp b/src/server/scihunt/monster_scientist.cpp index 968c78da..8c1fa528 100644 --- a/src/server/scihunt/monster_scientist.cpp +++ b/src/server/scihunt/monster_scientist.cpp @@ -438,7 +438,8 @@ void monster_scientist::Physics(void) input_movevalues = [0,0,0]; input_impulse = 0; input_buttons = 0; - + + if (style != SCI_DEAD) { if (!(m_iFlags & SCIF_SEEN)) { for (entity b = world; (b = find(b, ::classname, "player"));) { /* Find players in a 256 unit radius */ @@ -553,9 +554,6 @@ void monster_scientist::Physics(void) m_iFlags &= ~SCIF_SCARED; } - input_angles = angles = v_angle; - input_timelength = frametime; - if (m_flPainTime > time) { input_movevalues = [0,0,0]; } else { @@ -570,6 +568,11 @@ void monster_scientist::Physics(void) } } + } + + input_angles = angles = v_angle; + input_timelength = frametime; + runstandardplayerphysics(this); Footsteps_Update(); @@ -686,7 +689,7 @@ void monster_scientist::vDeath(int iHitBody) SendFlags |= NPC_FRAME; m_eUser = world; - customphysics = __NULL__; + //customphysics = __NULL__; m_iFlags = 0x0; if (health < -50) { diff --git a/src/shared/cstrike/player.cpp b/src/shared/cstrike/player.cpp new file mode 100644 index 00000000..ca95ba08 --- /dev/null +++ b/src/shared/cstrike/player.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +int input_sequence; +class player +{ + float health; + float armor; + + /* When the weapon is done firing */ + float w_attack_next; + /* When to play the next idle animation */ + float w_idle_next; + + /* Magazine/Clip */ + int a_ammo1; + /* Rest in the inventory */ + int a_ammo2; + /* Special ammo */ + int a_ammo3; + + /* We can't use the default .items field, because FTE will assume + * effects of some bits. Such as invisibility, quad, etc. */ + int g_items; + + float activeweapon; + float viewzoom; + vector view_ofs; + float weapontime; + + /* Weapon specific */ + int usp45_mag; + int glock18_mag; + int deagle_mag; + int p228_mag; + int elites_mag; + int fiveseven_mag; + int m3_mag; + int xm1014_mag; + int mp5_mag; + int p90_mag; + int ump45_mag; + int mac10_mag; + int tmp_mag; + int ak47_mag; + int sg552_mag; + int m4a1_mag; + int aug_mag; + int scout_mag; + int awp_mag; + int g3sg1_mag; + int sg550_mag; + int para_mag; + +#ifdef CSQC + /* External model */ + entity p_model; + int playertype; + int p_hand_bone; + int p_model_bone; + float pitch; + float lastweapon; + + /* Prediction */ + vector net_origin; + vector net_velocity; + float net_flags; + float net_w_attack_next; + float net_w_idle_next; + float net_jumptime; + float net_teleport_time; + float net_weapontime; + float net_viewzoom; + int net_ammo1; + int net_ammo2; + int net_ammo3; + int sequence; + + virtual void() gun_offset; + virtual void() draw; + virtual float() predraw; + virtual void() postdraw; +#else + int ammo_50ae; + int ammo_762mm; + int ammo_556mm; + int ammo_556mmbox; + int ammo_338mag; + int ammo_9mm; + int ammo_buckshot; + int ammo_45acp; + int ammo_357sig; + int ammo_57mm; + + /* conditional networking */ + int old_modelindex; + vector old_origin; + vector old_angles; + vector old_velocity; + int old_flags; + int old_activeweapon; + int old_items; + int old_health; + int old_armor; + int old_movetype; + int old_viewofs; + int old_baseframe; + int old_frame; + int old_a_ammo1; + int old_a_ammo2; + int old_a_ammo3; +#endif +}; diff --git a/src/shared/poke646/items.h b/src/shared/poke646/items.h new file mode 100644 index 00000000..427b87db --- /dev/null +++ b/src/shared/poke646/items.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define ITEM_HEATERPIPE 0x00000001i +#define ITEM_BRADNAILER 0x00000002i +#define ITEM_NAILGUN 0x00000004i +#define ITEM_SHOTGUN 0x00000008i +#define ITEM_CMLWBR 0x00000010i +#define ITEM_XS 0x00000020i +#define ITEM_PIPEBOMB 0x00000040i +#define ITEM_UNUSED8 0x00000080i + +#define ITEM_UNUSED9 0x00000100i +#define ITEM_UNUSED10 0x00000200i +#define ITEM_UNUSED11 0x00000400i +#define ITEM_UNUSED12 0x00000800i +#define ITEM_UNUSED13 0x00001000i +#define ITEM_UNUSED14 0x00002000i +#define ITEM_SUIT 0x00004000i +#define ITEM_LONGJUMP 0x00008000i + +#define ITEM_UNUSED17 0x00010000i +#define ITEM_UNUSED18 0x00020000i +#define ITEM_UNUSED19 0x00040000i +#define ITEM_UNUSED20 0x00080000i +#define ITEM_UNUSED21 0x00100000i +#define ITEM_UNUSED22 0x00200000i +#define ITEM_UNUSED23 0x00400000i +#define ITEM_UNUSED24 0x00800000i + +#define ITEM_UNUSED25 0x01000000i +#define ITEM_UNUSED26 0x02000000i +#define ITEM_UNUSED27 0x04000000i +#define ITEM_UNUSED28 0x08000000i +#define ITEM_UNUSED29 0x10000000i +#define ITEM_UNUSED30 0x20000000i +#define ITEM_UNUSED31 0x40000000i +#define ITEM_UNUSED32 0x80000000i diff --git a/src/shared/poke646/w_bradnailer.c b/src/shared/poke646/w_bradnailer.c new file mode 100644 index 00000000..2a5abde9 --- /dev/null +++ b/src/shared/poke646/w_bradnailer.c @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +enum +{ + BNAIL_IDLE1, + BNAIL_IDLE2, + BNAIL_IDLE3, + BNAIL_SHOOT, + BNAIL_UNUSED1, + BNAIL_RELOAD, + BNAIL_UNUSED2, + BNAIL_DRAW, + BNAIL_HOLSTER, + BNAIL_UNUSED3, + BNAIL_TILT, + BNAIL_TILTBACK, + BNAIL_SHOOT2 +}; + +void +w_bradnailer_precache(void) +{ + precache_sound("weapons/brad_hit1.wav"); + precache_sound("weapons/brad_hit2.wav"); + precache_sound("weapons/bradnailer.wav"); + + + precache_model("models/nail.mdl"); + precache_model("models/v_bradnailer.mdl"); + precache_model("models/w_bradnailer.mdl"); +} + +void +w_bradnailer_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, __NULL__, __NULL__, __NULL__); +#endif +} + +string +w_bradnailer_wmodel(void) +{ + return "models/w_bradnailer.mdl"; +} + +int +w_bradnailer_pickup(int new) +{ +/* TODO */ +} + +void +w_bradnailer_draw(void) +{ + Weapons_SetModel("models/v_bradnailer.mdl"); + Weapons_ViewAnimation(BNAIL_DRAW); +} + +void +w_bradnailer_holster(void) +{ + Weapons_ViewAnimation(BNAIL_HOLSTER); +} + +#ifdef SSQC +void +w_bradnailer_shootnail(void) +{ + player pl = (player)self; + static void Nail_Touch(void) { + Effect_CreateSpark(self.origin, trace_plane_normal); + if (other.takedamage == DAMAGE_YES) { + Damage_Apply(other, self.owner, 15, WEAPON_BRADNAILER, DMG_GENERIC); + if (random() < 0.5) { + Weapons_PlaySound(self, CHAN_WEAPON, "weapons/brad_hit1.wav", 1, ATTN_NORM); + } else { + Weapons_PlaySound(self, CHAN_WEAPON, "weapons/brad_hit2.wav", 1, ATTN_NORM); + } + } else { + Weapons_PlaySound(self, CHAN_WEAPON, "weapons/xbow_hit1.wav", 1, ATTN_NORM); + } + remove(self); + } + + Weapons_MakeVectors(); + entity nail = spawn(); + setmodel(nail, "models/nail.mdl"); + setorigin(nail, Weapons_GetCameraPos() + (v_forward * 16)); + nail.owner = self; + nail.velocity = v_forward * 2000; + nail.movetype = MOVETYPE_FLY; + nail.solid = SOLID_BBOX; + nail.angles = vectoangles(nail.velocity); + nail.avelocity[2] = 10; + nail.touch = Nail_Touch; + setsize(nail, [0,0,0], [0,0,0]); + + if (self.flags & FL_CROUCHING) + Animation_PlayerTopTemp(ANIM_SHOOT1HAND, 0.45f); + else + Animation_PlayerTopTemp(ANIM_CR_SHOOT1HAND, 0.45f); + + sound(pl, CHAN_WEAPON, "weapons/bradnailer.wav", 1, ATTN_NORM); +} +#endif + +void +w_bradnailer_primary(void) +{ + player pl = (player)self; + + if (pl.w_attack_next > 0.0) { + return; + } + +#ifdef SSQC + w_bradnailer_shootnail(); +#else + Weapons_ViewPunchAngle([-2,0,0]); + Weapons_ViewAnimation(BNAIL_SHOOT); +#endif + + pl.w_attack_next = 0.3f; + pl.w_idle_next = 5.0f; +} + +void +w_bradnailer_secondary(void) +{ + player pl = (player)self; + + if (pl.w_attack_next > 0.0) { + return; + } + + /* Hack */ + if (pl.a_ammo3 == 0) { + pl.a_ammo3 = 1; + Weapons_ViewAnimation(BNAIL_TILT); + pl.w_attack_next = 0.4f; + pl.w_idle_next = pl.w_attack_next; + return; + } + +#ifdef SSQC + w_bradnailer_shootnail(); +#else + Weapons_ViewPunchAngle([-2,0,0]); + Weapons_ViewAnimation(BNAIL_SHOOT2); +#endif + + pl.w_attack_next = 0.2f; + pl.w_idle_next = pl.w_attack_next; +} + + +void +w_bradnailer_release(void) +{ + player pl = (player)self; + + if (pl.w_idle_next > 0.0) { + return; + } + + if (pl.a_ammo3 == 1) { + pl.a_ammo3 = 0; + Weapons_ViewAnimation(BNAIL_TILTBACK); + pl.w_attack_next = 0.4f; + pl.w_idle_next = pl.w_attack_next; + return; + } + + int r = floor(random(0,3)); + switch (r) { + case 0: + Weapons_ViewAnimation(BNAIL_IDLE1); + break; + case 1: + Weapons_ViewAnimation(BNAIL_IDLE2); + break; + case 2: + Weapons_ViewAnimation(BNAIL_IDLE3); + break; + } + pl.w_idle_next = 10.0f; +} + +void +w_bradnailer_hudpic(int selected, vector pos) +{ +#ifdef CSQC + if (selected) { + drawsubpic( + pos, + [170,45], + "sprites/hud640_01.spr_0.tga", + [0,45/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } else { + drawsubpic( + pos, + [170,45], + "sprites/hud640_01.spr_0.tga", + [0,45/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } +#endif +} + +weapon_t w_bradnailer = +{ + .id = ITEM_BRADNAILER, + .slot = 1, + .slot_pos = 0, + .ki_spr = __NULL__, + .ki_size = __NULL__, + .ki_xy = __NULL__, + .draw = w_bradnailer_draw, + .holster = w_bradnailer_holster, + .primary = w_bradnailer_primary, + .secondary = w_bradnailer_secondary, + .reload = __NULL__, + .release = w_bradnailer_release, + .crosshair = __NULL__, + .precache = w_bradnailer_precache, + .pickup = w_bradnailer_pickup, + .updateammo = w_bradnailer_updateammo, + .wmodel = w_bradnailer_wmodel, + .pmodel = __NULL__, + .deathmsg = __NULL__, + .aimanim = __NULL__, + .hudpic = w_bradnailer_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_bradnailer(void) +{ + Weapons_InitItem(WEAPON_BRADNAILER); +} +#endif diff --git a/src/shared/poke646/w_cmlwbr.c b/src/shared/poke646/w_cmlwbr.c new file mode 100644 index 00000000..34d0bfe7 --- /dev/null +++ b/src/shared/poke646/w_cmlwbr.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +enum +{ + CML_IDLE1, + CML_IDLE2, + CML_IDLE3, + CML_IDLE4, + CML_FIRE1, + CML_RELOAD, + CML_DRAWBACK, + CML_UNDRAW, + CML_DRAW, + CML_UNUSED, + CML_HOLSTER +}; + +void +w_cmlwbr_precache(void) +{ + precache_sound("weapons/cmlwbr_drawback.wav"); + precache_sound("weapons/cmlwbr_fire.wav"); + precache_sound("weapons/cmlwbr_reload.wav"); + precache_sound("weapons/cmlwbr_undraw.wav"); + precache_sound("weapons/cmlwbr_zoom.wav"); + + precache_model("models/v_cmlwbr.mdl"); + precache_model("models/w_crossbow.mdl"); +} + +void +w_cmlwbr_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, __NULL__, __NULL__, __NULL__); +#endif +} + +string +w_cmlwbr_wmodel(void) +{ + return "models/w_crossbow.mdl"; +} + +void +w_cmlwbr_draw(void) +{ + Weapons_SetModel("models/v_cmlwbr.mdl"); + Weapons_ViewAnimation(CML_DRAW); +} + +void +w_cmlwbr_holster(void) +{ + Weapons_ViewAnimation(CML_HOLSTER); +} + +void +w_cmlwbr_primary(void) +{ +/* TODO, attack slows to crawl & player breathes */ +} + +void +w_cmlwbr_secondary(void) +{ + +} + + +void +w_cmlwbr_release(void) +{ + +} + +void +w_cmlwbr_hudpic(int selected, vector pos) +{ +#ifdef CSQC + if (selected) { + drawsubpic( + pos, + [170,45], + "sprites/hud640_03.spr_0.tga", + [0,45/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } else { + drawsubpic( + pos, + [170,45], + "sprites/hud640_03.spr_0.tga", + [0,45/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } +#endif +} + +weapon_t w_cmlwbr = +{ + .id = ITEM_CMLWBR, + .slot = 2, + .slot_pos = 1, + .ki_spr = __NULL__, + .ki_size = __NULL__, + .ki_xy = __NULL__, + .draw = w_cmlwbr_draw, + .holster = w_cmlwbr_holster, + .primary = w_cmlwbr_primary, + .secondary = w_cmlwbr_secondary, + .reload = __NULL__, + .release = w_cmlwbr_release, + .crosshair = __NULL__, + .precache = w_cmlwbr_precache, + .pickup = __NULL__, + .updateammo = w_cmlwbr_updateammo, + .wmodel = w_cmlwbr_wmodel, + .pmodel = __NULL__, + .deathmsg = __NULL__, + .aimanim = __NULL__, + .hudpic = w_cmlwbr_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_cmlwbr(void) +{ + Weapons_InitItem(WEAPON_CMLWBR); +} +#endif diff --git a/src/shared/poke646/w_heaterpipe.c b/src/shared/poke646/w_heaterpipe.c new file mode 100644 index 00000000..40e463ae --- /dev/null +++ b/src/shared/poke646/w_heaterpipe.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +enum +{ + HPIPE_IDLE1, + HPIPE_DRAW, + HPIPE_HOLSTER, + HPIPE_ATTACK1, + HPIPE_ATTACK1MISS, + HPIPE_ATTACK2MISS, + HPIPE_ATTACK2, + HPIPE_ATTACK3MISS, + HPIPE_ATTACK3 +}; + +void +w_heaterpipe_precache(void) +{ + precache_sound("weapons/pipe_hit1.wav"); + precache_sound("weapons/pipe_hit2.wav"); + precache_sound("weapons/pipe_miss.wav"); + + precache_model("models/v_heaterpipe.mdl"); + precache_model("models/w_heaterpipe.mdl"); +} + +void +w_heaterpipe_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, __NULL__, __NULL__, __NULL__); +#endif +} + +string +w_heaterpipe_wmodel(void) +{ + return "models/w_heaterpipe.mdl"; +} + +void +w_heaterpipe_draw(void) +{ + Weapons_SetModel("models/v_heaterpipe.mdl"); + Weapons_ViewAnimation(HPIPE_DRAW); +} + +void +w_heaterpipe_holster(void) +{ + Weapons_ViewAnimation(HPIPE_HOLSTER); +} + +void +w_heaterpipe_primary(void) +{ +/* TODO, attack slows to crawl & player breathes */ +} + +void +w_heaterpipe_release(void) +{ + +} + +void +w_heaterpipe_hudpic(int selected, vector pos) +{ +#ifdef CSQC + if (selected) { + drawsubpic( + pos, + [170,45], + "sprites/hud640_01.spr_0.tga", + [0,45/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } else { + drawsubpic( + pos, + [170,45], + "sprites/hud640_01.spr_0.tga", + [0,45/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } +#endif +} + +weapon_t w_heaterpipe = +{ + .id = ITEM_HEATERPIPE, + .slot = 0, + .slot_pos = 0, + .ki_spr = __NULL__, + .ki_size = __NULL__, + .ki_xy = __NULL__, + .draw = w_heaterpipe_draw, + .holster = w_heaterpipe_holster, + .primary = w_heaterpipe_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = w_heaterpipe_release, + .crosshair = __NULL__, + .precache = w_heaterpipe_precache, + .pickup = __NULL__, + .updateammo = w_heaterpipe_updateammo, + .wmodel = w_heaterpipe_wmodel, + .pmodel = __NULL__, + .deathmsg = __NULL__, + .aimanim = __NULL__, + .hudpic = w_heaterpipe_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_heaterpipe(void) +{ + Weapons_InitItem(WEAPON_HEATERPIPE); +} +#endif diff --git a/src/shared/poke646/w_nailgun.c b/src/shared/poke646/w_nailgun.c new file mode 100644 index 00000000..9f914a2e --- /dev/null +++ b/src/shared/poke646/w_nailgun.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +enum +{ + NAIL_IDLE1, + NAIL_IDLE2, + NAIL_UNUSED1, + NAIL_RELOAD, + NAIL_DRAW, + NAIL_SHOOT +}; + +void +w_nailgun_precache(void) +{ + precache_sound("weapons/brad_hit1.wav"); + precache_sound("weapons/brad_hit2.wav"); + precache_sound("weapons/nailgun.wav"); + + precache_model("models/nail.mdl"); + precache_model("models/v_nailgun.mdl"); + precache_model("models/w_nailgun.mdl"); +} + +void +w_nailgun_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, __NULL__, __NULL__, __NULL__); +#endif +} + +string +w_nailgun_wmodel(void) +{ + return "models/w_nailgun.mdl"; +} + +void +w_nailgun_draw(void) +{ + Weapons_SetModel("models/v_nailgun.mdl"); + Weapons_ViewAnimation(NAIL_DRAW); +} + +void +w_nailgun_primary(void) +{ + player pl = (player)self; + + if (pl.w_attack_next > 0.0) { + return; + } + +#ifdef SSQC + static void Nail_Touch(void) { + Effect_CreateSpark(self.origin, trace_plane_normal); + if (other.takedamage == DAMAGE_YES) { + Damage_Apply(other, self.owner, 15, WEAPON_NAILGUN, DMG_GENERIC); + if (random() < 0.5) { + Weapons_PlaySound(self, CHAN_WEAPON, "weapons/brad_hit1.wav", 1, ATTN_NORM); + } else { + Weapons_PlaySound(self, CHAN_WEAPON, "weapons/brad_hit2.wav", 1, ATTN_NORM); + } + } else { + Weapons_PlaySound(self, CHAN_WEAPON, "weapons/xbow_hit1.wav", 1, ATTN_NORM); + } + remove(self); + } + + Weapons_MakeVectors(); + entity nail = spawn(); + setmodel(nail, "models/nail.mdl"); + setorigin(nail, Weapons_GetCameraPos() + (v_forward * 16)); + nail.owner = self; + nail.velocity = v_forward * 2000; + nail.movetype = MOVETYPE_FLY; + nail.solid = SOLID_BBOX; + nail.angles = vectoangles(nail.velocity); + nail.avelocity[2] = 10; + nail.touch = Nail_Touch; + setsize(nail, [0,0,0], [0,0,0]); + + if (self.flags & FL_CROUCHING) + Animation_PlayerTopTemp(ANIM_SHOOT1HAND, 0.45f); + else + Animation_PlayerTopTemp(ANIM_CR_SHOOT1HAND, 0.45f); + + Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/nailgun.wav", 1, ATTN_NORM); + +#else + + Weapons_ViewPunchAngle([-2,0,0]); + Weapons_ViewAnimation(NAIL_SHOOT); + + +#endif + + pl.w_attack_next = 0.1f; + pl.w_idle_next = 5.0f; +} + +void +w_nailgun_release(void) +{ + + player pl = (player)self; + if (pl.w_idle_next > 0) { + return; + } + + if (random() < 0.5) { + Weapons_ViewAnimation(NAIL_IDLE1); + } else { + Weapons_ViewAnimation(NAIL_IDLE2); + } + pl.w_idle_next = 10.0f; + +} + + +void +w_nailgun_hudpic(int selected, vector pos) +{ +#ifdef CSQC + if (selected) { + drawsubpic( + pos, + [170,45], + "sprites/hud640_01.spr_0.tga", + [0,45/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } else { + drawsubpic( + pos, + [170,45], + "sprites/hud640_01.spr_0.tga", + [0,45/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } +#endif +} + +weapon_t w_nailgun = +{ + .id = ITEM_NAILGUN, + .slot = 1, + .slot_pos = 1, + .ki_spr = __NULL__, + .ki_size = __NULL__, + .ki_xy = __NULL__, + .draw = w_nailgun_draw, + .holster = __NULL__, + .primary = w_nailgun_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = w_nailgun_release, + .crosshair = __NULL__, + .precache = w_nailgun_precache, + .pickup = __NULL__, + .updateammo = w_nailgun_updateammo, + .wmodel = w_nailgun_wmodel, + .pmodel = __NULL__, + .deathmsg = __NULL__, + .aimanim = __NULL__, + .hudpic = w_nailgun_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_nailgun(void) +{ + Weapons_InitItem(WEAPON_NAILGUN); +} +#endif diff --git a/src/shared/poke646/w_pipebomb.c b/src/shared/poke646/w_pipebomb.c new file mode 100644 index 00000000..03d57d05 --- /dev/null +++ b/src/shared/poke646/w_pipebomb.c @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +enum +{ + PIPEB_IDLE, + PIPEB_FIDGET, + PIPEB_DRAW, + PIPEB_THROW +}; + +enum +{ + WATCH_IDLE, + WATCH_FIDGET, + WATCH_DRAW, + WATCH_USE, + WATCH_HOLSTER +}; + +void w_pipebomb_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, pl.satchel_chg, pl.ammo_satchel, __NULL__); +#endif +} +string w_pipebomb_wmodel(void) +{ + return "models/w_pipebomb.mdl"; +} +void w_pipebomb_precache(void) +{ + precache_sound("weapons/pb_bounce1.wav"); + precache_sound("weapons/pb_bounce2.wav"); precache_sound("weapons/pb_bounce3.wav"); + + precache_model("models/v_pipebomb.mdl"); + precache_model("models/v_pipebomb_watch.mdl"); + precache_model("models/w_pipebomb.mdl"); +} + +int w_pipebomb_pickup(int new) +{ +#ifdef SSQC + player pl = (player)self; + + if (pl.ammo_satchel < 5) { + pl.ammo_satchel = bound(0, pl.ammo_satchel + 1, 5); + } else { + return FALSE; + } +#endif + return TRUE; +} + +void w_pipebomb_draw(void) +{ + Weapons_SetModel("models/v_pipebomb.mdl"); + Weapons_ViewAnimation(PIPEB_DRAW); +#ifdef SSQC + player pl = (player)self; + Weapons_UpdateAmmo(pl, pl.satchel_chg, pl.ammo_satchel, __NULL__); +#endif +} + +void w_pipebomb_holster(void) +{ + +} + +#ifdef SSQC +void s_pipebomb_drop(entity master, vector src, vector vel) +{ + entity satch; + satch = spawn(); + satch.owner = master; + satch.classname = "satchel"; + satch.movetype = MOVETYPE_BOUNCE; + satch.solid = SOLID_BBOX; + satch.frame = 1; + satch.gravity = 0.5f; + satch.friction = 0.8f; + satch.velocity = vel; + satch.avelocity = [0,400,0]; + setmodel(satch, "models/w_pipebomb.mdl"); + setsize(satch, [-4,-4,-4], [4,4,4]); + setorigin(satch, src); +} +void s_pipebomb_detonate(entity master) +{ + for (entity b = world; (b = find(b, ::classname, "satchel"));) { + if (b.owner == master) { + Effect_CreateExplosion(b.origin); + Damage_Radius(b.origin, master, 150, 150 * 2.5f, TRUE, WEAPON_PIPEBOMB); + sound(b, CHAN_WEAPON, sprintf( "weapons/explode%d.wav", floor( random() * 2 ) + 3 ), 1, ATTN_NORM); + remove(b); + } + } +} +#endif + +void w_pipebomb_primary(void) +{ + player pl = (player)self; + + if (pl.w_attack_next) { + return; + } + + /* Ammo check */ +#ifdef CSQC + if (pl.a_ammo1 <= 0 && pl.a_ammo2 <= 0) { + return; + } +#else + if (pl.satchel_chg <= 0 && pl.ammo_satchel <= 0) { + return; + } +#endif + + if (pl.a_ammo1 <= 0) { + Weapons_ViewAnimation(WATCH_DRAW); + } else { + Weapons_ViewAnimation(WATCH_USE); + } + +#ifdef SSQC + if (!pl.satchel_chg) { + vector throw; + + Weapons_MakeVectors(); + throw = pl.velocity + (v_forward * 274); + s_pipebomb_drop(self, pl.origin, throw); + pl.satchel_chg++; + pl.ammo_satchel--; + } else { + s_pipebomb_detonate(pl); + pl.satchel_chg = 0; + + if (pl.ammo_satchel <= 0) { + Weapons_RemoveItem(pl, WEAPON_PIPEBOMB); + } + } + Weapons_UpdateAmmo(pl, pl.satchel_chg, pl.ammo_satchel, __NULL__); +#else + setmodel(pSeat->eViewModel, "models/v_pipebomb_watch.mdl"); + pl.a_ammo1++; + pl.a_ammo2--; +#endif + + pl.w_attack_next = 1.0f; + pl.w_idle_next = 1.0f; +} +void w_pipebomb_secondary(void) +{ + player pl = (player)self; + + if (pl.w_attack_next) { + return; + } + + /* Ammo check */ +#ifdef CSQC + if (pl.a_ammo2 <= 0) { + return; + } +#else + if (pl.ammo_satchel <= 0) { + return; + } +#endif + +#ifdef SSQC + vector throw; + Weapons_MakeVectors(); + throw = pl.velocity + (v_forward * 274); + s_pipebomb_drop(self, pl.origin, throw); + pl.satchel_chg++; + pl.ammo_satchel--; + Weapons_UpdateAmmo(pl, pl.satchel_chg, pl.ammo_satchel, __NULL__); +#else + pl.a_ammo1++; + pl.a_ammo2--; + setmodel(pSeat->eViewModel, "models/v_pipebomb_watch.mdl"); +#endif + + Weapons_ViewAnimation(WATCH_DRAW); + + pl.w_attack_next = 1.0f; + pl.w_idle_next = 2.5f; +} +void +w_pipebomb_reload(void) +{ + +} +void +w_pipebomb_release(void) +{ + player pl = (player)self; + + if (pl.w_idle_next > 0.0) { + return; + } + + if (pl.a_ammo1 <= 0) { + Weapons_ViewAnimation(PIPEB_FIDGET); + } else { + Weapons_ViewAnimation(WATCH_FIDGET); + } + pl.w_idle_next = 15.0f; +} + +float +w_pipebomb_aimanim(void) +{ + return self.flags & FL_CROUCHING ? ANIM_CR_AIMSQUEAK : ANIM_AIMSQUEAK; +} + +void +w_pipebomb_hud(void) +{ +#ifdef CSQC + HUD_DrawAmmo2(); + vector aicon_pos = video_mins + [video_res[0] - 48, video_res[1] - 42]; + drawsubpic(aicon_pos, [24,24], "sprites/640hud7.spr_0.tga", [72/256,96/128], [24/256, 24/128], g_hud_color, pSeat->ammo2_alpha, DRAWFLAG_ADDITIVE); +#endif +} + +void +w_pipebomb_hudpic(int s, vector pos) +{ +#ifdef CSQC + if (s) { + drawsubpic(pos, [170,45], "sprites/640hud6.spr_0.tga", [0,45/256], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE); + } else { + drawsubpic(pos, [170,45], "sprites/640hud3.spr_0.tga", [0,45/256], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE); + } +#endif +} + +weapon_t w_pipebomb = +{ + .id = ITEM_PIPEBOMB, + .slot = 4, + .slot_pos = 0, + .ki_spr = __NULL__, + .ki_size = __NULL__, + .ki_xy = __NULL__, + .draw = w_pipebomb_draw, + .holster = w_pipebomb_holster, + .primary = w_pipebomb_primary, + .secondary = w_pipebomb_secondary, + .reload = __NULL__, + .release = w_pipebomb_release, + .crosshair = __NULL__, + .precache = w_pipebomb_precache, + .pickup = __NULL__, + .updateammo = w_pipebomb_updateammo, + .wmodel = w_pipebomb_wmodel, + .pmodel = __NULL__, + .deathmsg = __NULL__, + .aimanim = __NULL__, + .hudpic = w_pipebomb_hudpic +}; + +#ifdef SSQC +void weapon_pipebomb(void) { + Weapons_InitItem(WEAPON_PIPEBOMB); +} +#endif + diff --git a/src/shared/poke646/w_shotgun.c b/src/shared/poke646/w_shotgun.c new file mode 100644 index 00000000..4ec078d1 --- /dev/null +++ b/src/shared/poke646/w_shotgun.c @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +enum +{ + SHOTGUN_IDLE1, + SHOTGUN_FIRE1, + SHOTGUN_RELOAD, + SHOTGUN_PUMP, + SHOTGUN_START_RELOAD, + SHOTGUN_DRAW, + SHOTGUN_HOLSTER, + SHOTGUN_IDLE2 +}; + +enum +{ + SHOTTY_IDLE, + SHOTTY_RELOAD_START, + SHOTTY_RELOAD, + SHOTTY_RELOAD_END +}; + +void w_shotgun_precache(void) +{ + precache_model("models/v_shotgun.mdl"); + precache_model("models/w_shotgun.mdl"); + precache_model("models/p_shotgun.mdl"); + precache_sound("weapons/sbarrel1.wav"); + precache_sound("weapons/dbarrel1.wav"); + precache_sound("weapons/reload3.wav"); + precache_sound("weapons/scock1.wav"); +} +void w_shotgun_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_buckshot, __NULL__); +#endif +} +string w_shotgun_wmodel(void) +{ + return "models/w_shotgun.mdl"; +} +string w_shotgun_pmodel(void) +{ + return "models/p_shotgun.mdl"; +} +string w_shotgun_deathmsg(void) +{ + return ""; +} + +int w_shotgun_pickup(int new) +{ +#ifdef SSQC + player pl = (player)self; + + if (new) { + pl.shotgun_mag = 8; + } else { + if (pl.ammo_buckshot < 125) { + pl.ammo_buckshot = bound(0, pl.ammo_buckshot + 8, 125); + } else { + return FALSE; + } + } +#endif + return TRUE; +} + +void w_shotgun_draw(void) +{ + Weapons_SetModel("models/v_shotgun.mdl"); + Weapons_ViewAnimation(SHOTGUN_DRAW); +#ifdef SSQC + player pl = (player)self; + Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_buckshot, __NULL__); +#endif +} + +void w_shotgun_holster(void) +{ + Weapons_ViewAnimation(SHOTGUN_HOLSTER); +} +void w_shotgun_primary(void) +{ + player pl = (player)self; + if (pl.w_attack_next) { + return; + } + + if (pl.a_ammo3 > SHOTTY_IDLE) { + return; + } + + /* Ammo check */ +#ifdef SSQC + if (pl.shotgun_mag <= 0) { + return; + } +#else + if (pl.a_ammo1 <= 0) { + return; + } +#endif + +#ifdef SSQC + /* Singleplayer is more accurate */ + if (cvar("sv_playerslots") == 1) { + TraceAttack_FireBullets(6, pl.origin + pl.view_ofs, 5, [0.08716,0.08716], WEAPON_SHOTGUN); + } else { + TraceAttack_FireBullets(4, pl.origin + pl.view_ofs, 5, [0.08716,0.04362], WEAPON_SHOTGUN); + } + Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/dbarrel1.wav", 1, ATTN_NORM); + pl.shotgun_mag--; + Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_buckshot, __NULL__); +#else + View_SetMuzzleflash(MUZZLE_WEIRD); + Weapons_ViewPunchAngle([-5,0,0]); + pl.a_ammo1--; +#endif + Weapons_ViewAnimation(SHOTGUN_FIRE1); + + pl.w_attack_next = 1.1f; + pl.w_idle_next = 2.5f; +} +void w_shotgun_reload(void) +{ + player pl = (player)self; +#ifdef CSQC + if (pl.a_ammo1 >= 8) { + return; + } + if (pl.a_ammo2 <= 0) { + return; + } +#else + if (pl.shotgun_mag >= 8) { + return; + } + if (pl.ammo_buckshot <= 0) { + return; + } +#endif + + if (pl.a_ammo3 > SHOTTY_IDLE) { + return; + } + pl.a_ammo3 = SHOTTY_RELOAD_START; + pl.w_idle_next = 0.0f; +} +void w_shotgun_release(void) +{ + player pl = (player)self; + + if (pl.w_idle_next > 0.0) { + return; + } + + if (pl.a_ammo3 == SHOTTY_IDLE) { + int r = floor(random(0,2)); + switch (r) { + case 0: + Weapons_ViewAnimation(SHOTGUN_IDLE1); + break; + case 1: + Weapons_ViewAnimation(SHOTGUN_IDLE2); + break; + } + pl.w_idle_next = 15.0f; + } else if (pl.a_ammo3 == SHOTTY_RELOAD_START) { + Weapons_ViewAnimation(SHOTGUN_START_RELOAD); + pl.a_ammo3 = SHOTTY_RELOAD; + pl.w_idle_next = 0.65f; + } else if (pl.a_ammo3 == SHOTTY_RELOAD) { + Weapons_ViewAnimation(SHOTGUN_RELOAD); +#ifdef CSQC + pl.a_ammo1++; + pl.a_ammo2--; + + if (pl.a_ammo2 <= 0 || pl.a_ammo1 >= 8) { + pl.a_ammo3 = SHOTTY_RELOAD_END; + } +#else + pl.shotgun_mag++; + pl.ammo_buckshot--; + Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_buckshot, pl.a_ammo3); + sound(pl, CHAN_WEAPON, "weapons/reload3.wav", 1.0, ATTN_NORM); + if (pl.ammo_buckshot <= 0 || pl.shotgun_mag >= 8) { + pl.a_ammo3 = SHOTTY_RELOAD_END; + } +#endif + pl.w_idle_next = 0.5f; + } else if (pl.a_ammo3 == SHOTTY_RELOAD_END) { + Weapons_ViewAnimation(SHOTGUN_PUMP); +#ifdef SSQC + sound(pl, CHAN_WEAPON, "weapons/scock1.wav", 1.0, ATTN_NORM); +#endif + pl.a_ammo3 = SHOTTY_IDLE; + pl.w_idle_next = 10.0f; + pl.w_attack_next = 0.5f; + } +} +void w_shotgun_crosshair(void) +{ +#ifdef CSQC + static vector cross_pos; + cross_pos = (video_res / 2) + [-12,-12]; + drawsubpic(cross_pos, [24,24], "sprites/crosshairs.spr_0.tga", [48/128,24/128], [0.1875, 0.1875], [1,1,1], 1, DRAWFLAG_NORMAL); + HUD_DrawAmmo1(); + HUD_DrawAmmo2(); + vector aicon_pos = video_mins + [video_res[0] - 48, video_res[1] - 42]; + drawsubpic(aicon_pos, [24,24], "sprites/640hud7.spr_0.tga", [72/256,72/128], [24/256, 24/128], g_hud_color, pSeat->ammo2_alpha, DRAWFLAG_ADDITIVE); +#endif +} + +float w_shotgun_aimanim(void) +{ + return self.flags & FL_CROUCHING ? ANIM_CR_AIMSHOTGUN : ANIM_AIMSHOTGUN; +} + +void w_shotgun_hudpic(int s, vector pos) +{ +#ifdef CSQC + if (s) { + drawsubpic(pos, [170,45], "sprites/640hud4.spr_0.tga", [0,180/256], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE); + } else { + drawsubpic(pos, [170,45], "sprites/640hud1.spr_0.tga", [0,180/256], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE); + } +#endif +} + +weapon_t w_shotgun = +{ + .id = ITEM_SHOTGUN, + .slot = 2, + .slot_pos = 0, + .ki_spr = __NULL__, + .ki_size = __NULL__, + .ki_xy = __NULL__, + .draw = w_shotgun_draw, + .holster = w_shotgun_holster, + .primary = w_shotgun_primary, + .secondary = __NULL__, + .reload = w_shotgun_reload, + .release = w_shotgun_release, + .crosshair = __NULL__, + .precache = w_shotgun_precache, + .pickup = w_shotgun_pickup, + .updateammo = w_shotgun_updateammo, + .wmodel = w_shotgun_wmodel, + .pmodel = __NULL__, + .deathmsg = __NULL__, + .aimanim = __NULL__, + .hudpic = w_shotgun_hudpic +}; + +#ifdef SSQC +void weapon_shotgun(void) { + Weapons_InitItem(WEAPON_SHOTGUN); +} +#endif diff --git a/src/shared/poke646/w_xs.c b/src/shared/poke646/w_xs.c new file mode 100644 index 00000000..dfef0a57 --- /dev/null +++ b/src/shared/poke646/w_xs.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +enum +{ + XS_IDLE1, + XS_IDLE2, + XS_IDLE3, + XS_SPINUP, + XS_SPIN, + XS_FIRE1, + XS_FIRE2, + XS_HOLSTER, + XS_DRAW, + XS_RELOAD +}; + +void +w_xs_precache(void) +{ + precache_sound("weapons/xs_moan1.wav"); + precache_sound("weapons/xs_moan2.wav"); + precache_sound("weapons/xs_moan3.wav"); + precache_sound("weapons/xs_reload.wav"); + precache_sound("weapons/xs_shot.wav"); + precache_sound("weapons/xs_windup.wav"); + + precache_model("models/v_xs.mdl"); + precache_model("models/w_xs.mdl"); +} + +void +w_xs_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, __NULL__, __NULL__, __NULL__); +#endif +} + +string +w_xs_wmodel(void) +{ + return "models/w_xs.mdl"; +} + +void +w_xs_draw(void) +{ + Weapons_SetModel("models/v_xs.mdl"); + Weapons_ViewAnimation(XS_DRAW); +} + +void +w_xs_holster(void) +{ + Weapons_ViewAnimation(XS_HOLSTER); +} + +void +w_xs_primary(void) +{ +/* TODO */ +} + +void +w_xs_secondary(void) +{ + +/* TODO Charge up, uses ammo similar to gauss */ + +} + + +void +w_xs_release(void) +{ + +} + +void +w_xs_hudpic(int selected, vector pos) +{ +#ifdef CSQC + if (selected) { + drawsubpic( + pos, + [170,45], + "sprites/hud640_01.spr_0.tga", + [0,45/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } else { + drawsubpic( + pos, + [170,45], + "sprites/hud640_01.spr_0.tga", + [0,45/256], + [170/256,45/256], + g_hud_color, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } +#endif +} + +weapon_t w_xs = +{ + .id = ITEM_XS, + .slot = 3, + .slot_pos = 0, + .ki_spr = __NULL__, + .ki_size = __NULL__, + .ki_xy = __NULL__, + .draw = w_xs_draw, + .holster = w_xs_holster, + .primary = w_xs_primary, + .secondary = w_xs_secondary, + .reload = __NULL__, + .release = w_xs_release, + .crosshair = __NULL__, + .precache = w_xs_precache, + .pickup = __NULL__, + .updateammo = w_xs_updateammo, + .wmodel = w_xs_wmodel, + .pmodel = __NULL__, + .deathmsg = __NULL__, + .aimanim = __NULL__, + .hudpic = w_xs_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_xs(void) +{ + Weapons_InitItem(WEAPON_XS); +} +#endif diff --git a/src/shared/poke646/weapons.c b/src/shared/poke646/weapons.c new file mode 100644 index 00000000..c7e22b30 --- /dev/null +++ b/src/shared/poke646/weapons.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +weapon_t w_null = {}; +weapon_t g_weapons[] = { + w_null, + w_heaterpipe, + w_bradnailer, + w_nailgun, + w_shotgun, + w_cmlwbr, + w_xs, + w_pipebomb +}; diff --git a/src/shared/poke646/weapons.h b/src/shared/poke646/weapons.h new file mode 100644 index 00000000..955c4263 --- /dev/null +++ b/src/shared/poke646/weapons.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* Weapon Indices for the weapon table */ +enum +{ + WEAPON_NONE, + WEAPON_HEATERPIPE, + WEAPON_BRADNAILER, + WEAPON_NAILGUN, + WEAPON_SHOTGUN, + WEAPON_CMLWBR, + WEAPON_XS, + WEAPON_PIPEBOMB +};