diff --git a/src/client/defs.h b/src/client/defs.h index 1932352..a355cb6 100644 --- a/src/client/defs.h +++ b/src/client/defs.h @@ -56,6 +56,8 @@ struct int m_iHUDWeaponSelected; float m_flHUDWeaponSelectTime; int m_iItemsOld; + + float m_flDamageIndicator; } g_seatslocal[4], *pSeatLocal; void HUD_DrawAmmo1(void); diff --git a/src/client/flashlight.qc b/src/client/flashlight.qc index aa3981a..e2ae45e 100644 --- a/src/client/flashlight.qc +++ b/src/client/flashlight.qc @@ -17,27 +17,5 @@ void Player_Flashlight(NSClientPlayer pl) { - if (pl.gflags & GF_FLASHLIGHT) { - vector src; - vector ang; - - if (pl.entnum != player_localentnum) { - src = pl.origin + pl.view_ofs; - ang = pl.v_angle; - } else { - src = pSeat->m_vecPredictedOrigin + [0,0,-8]; - ang = view_angles; - } - makevectors(ang); - traceline(src, src + (v_forward * 8096), MOVE_NORMAL, pl); - - if (serverkeyfloat("*bspversion") == BSPVER_HL) { - dynamiclight_add(trace_endpos + (v_forward * -2), 128, [1,1,1]); - } else { - float p = dynamiclight_add(src, 512, [1,1,1], 0, "textures/flashlight"); - dynamiclight_set(p, LFIELD_ANGLES, ang); - dynamiclight_set(p, LFIELD_FLAGS, 3); - } - } } diff --git a/src/client/game_event.qc b/src/client/game_event.qc index 2038bb4..36e62cb 100644 --- a/src/client/game_event.qc +++ b/src/client/game_event.qc @@ -21,6 +21,9 @@ ClientGame_EventParse(float fHeader) case EV_OBITUARY: Obituary_Parse(); break; + case EV_HITNOTIFY: + pSeatLocal->m_flDamageIndicator = 1.0f; + break; case EV_SPARK: vector vSparkPos, vSparkAngle; vSparkPos[0] = readcoord(); diff --git a/src/client/hud.qc b/src/client/hud.qc index f8dfc75..e133ec1 100644 --- a/src/client/hud.qc +++ b/src/client/hud.qc @@ -431,6 +431,30 @@ HUD_WeaponPickupNotify(int w) pSeatLocal->m_flPickupAlpha = 2.5f; } +void +HUD_DrawDamageIndicator(void) +{ + vector cross_pos; + + if (pSeatLocal->m_flDamageIndicator <= 0.0) + return; + + cross_pos = g_hudmins + (g_hudres / 2) + [-12,-12]; + + /*drawsubpic( + cross_pos, + [24,24], + g_cross_spr, + [0.0, 72/128], + [0.1875, 0.1875], + [1,1,1] * pSeatLocal->m_flDamageIndicator, + 1.0f, + DRAWFLAG_ADDITIVE + );*/ + + pSeatLocal->m_flDamageIndicator -= clframetime; +} + /* main entry */ void HUD_Draw(void) @@ -441,6 +465,7 @@ HUD_Draw(void) /* little point in not drawing these, even if you don't have a suit */ Weapons_DrawCrosshair(pl); + HUD_DrawDamageIndicator(); HUD_DrawWeaponSelect(); Obituary_Draw(); Textmenu_Draw(); diff --git a/src/client/player.qc b/src/client/player.qc deleted file mode 100644 index c8f890f..0000000 --- a/src/client/player.qc +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2016-2020 Marco Cawthorne - * - * 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. - */ - -string g_pbones[] = -{ - "Bip01", - "Bip01 Footsteps", - "Bip01 Pelvis", - "Bip01 L Leg", - "Bip01 L Leg1", - "Bip01 L Foot", - "Bip01 L Toe0", - "Bip01 L Toe01", - "Bip01 L Toe02", - "Dummy16", - "Bip01 R Leg", - "Bip01 R Leg1", - "Bip01 R Foot", - "Bip01 R Toe0", - "Bip01 R Toe01", - "Bip01 R Toe02", - "Dummy11", - "Bip01 Spine", - "Bip01 Spine1", - "Bip01 Spine2", - "Bip01 Spine3", - "Bip01 Neck", - "Bip01 Head", - "Dummy21", - "Dummy08", - "Bone02", - "Bone03", - "Bone04", - "Dummy05", - "Bone09", - "Bone10", - "Dummy04", - "Bone05", - "Bone06", - "Dummy03", - "Bone07", - "Bone08", - "Dummy09", - "Bone11", - "Bone12", -"Dummy10", - "Bone13", - "Bone14", - "Bone15", - "Bip01 L Arm", - "Bip01 L Arm1", - "Bip01 L Arm2", - "Bip01 L Hand", - "Bip01 L Finger0", - "Bip01 L Finger01", - "Bip01 L Finger02", - "Dummy06", - "Bip01 L Finger1", - "Bip01 L Finger11", - "Bip01 L Finger12", - "Dummy07", - "Bip01 R Arm", - "Bip01 R Arm1", - "Bip01 R Arm2", - "Bip01 R Hand", - "Bip01 R Finger0", - "Bip01 R Finger01", - "Bip01 R Finger02", - "Dummy01", - "Bip01 R Finger1", - "Bip01 R Finger11", - "Bip01 R Finger12", - "Dummy02", - "Box02", - "Bone08", - "Bone15" -}; - -.string oldmodel; -void -Player_HandleWeaponModel(NSClientPlayer pp, float thirdperson) -{ - player pl = (player)pp; - - /* if we don't exist, create us */ - if (!pl.p_model) { - pl.p_model = spawn(); - } - - /* what's the current weapon model supposed to be anyway? */ - pl.p_model.oldmodel = Weapons_GetPlayermodel(pl, pl.activeweapon); - - /* we changed weapons, update skeletonindex */ - if (pl.p_model.model != pl.p_model.oldmodel) { - /* free memory */ - if (pl.p_model.skeletonindex) - skel_delete(pl.p_model.skeletonindex); - - /* set the new model and mark us updated */ - setmodel(pl.p_model, pl.p_model.oldmodel); - pl.p_model.model = pl.p_model.oldmodel; - - /* set the new skeletonindex */ - pl.p_model.skeletonindex = skel_create(pl.p_model.modelindex); - - /* hack this thing in here FIXME: this should be done when popping in/out of a pvs */ - if (autocvar(cl_himodels, 1, "Use high-quality player models over lower-definition ones")) - setcustomskin(pl, "", "geomset 0 2\n"); - else - setcustomskin(pl, "", "geomset 0 1\n"); - } - - /* follow player at all times */ - setorigin(pl.p_model, pl.origin); - pl.p_model.angles = pl.angles; - skel_build(pl.p_model.skeletonindex, pl.p_model, pl.p_model.modelindex,0, 0, -1); - - /* we have to loop through all valid bones of the weapon model and match them - * to the player one */ - for (float i = 0; i < g_pbones.length; i++) { - vector bpos; - float pbone = gettagindex(pl, g_pbones[i]); - float wbone = gettagindex(pl.p_model, g_pbones[i]); - - /* if the bone doesn't ignore in either skeletal mesh, ignore */ - if (wbone <= 0 || pbone <= 0) - continue; - - bpos = gettaginfo(pl, pbone); - - /* the most expensive bit */ - skel_set_bone_world(pl.p_model, wbone, bpos, v_forward, v_right, v_up); - } -} - -void -Player_PreDraw(NSClientPlayer pp, int thirdperson) -{ - player pl = (player)pp; - - /* Handle the flashlights... */ - Player_Flashlight(pl); - - Weapons_PreDraw(pl, thirdperson); - - //pl.Physics_SetViewParms(); - - if (thirdperson) - Player_HandleWeaponModel(pl, thirdperson); -} diff --git a/src/client/progs.src b/src/client/progs.src index 1b5a118..6531b81 100644 --- a/src/client/progs.src +++ b/src/client/progs.src @@ -24,7 +24,6 @@ defs.h damage.qc init.qc flashlight.qc -player.qc entities.qc cmds.qc game_event.qc diff --git a/src/shared/player.qc b/src/shared/player.qc index a0fdbb4..36d5627 100644 --- a/src/shared/player.qc +++ b/src/shared/player.qc @@ -14,7 +14,90 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* all potential SendFlags bits we can possibly send */ +#ifdef CLIENT +/* Here's a list of bone names that we are aware of on HL player models. + Usually we'd use skeletalobjects to share the same skeleton/anim with + another model - but because FTEQW does not support that for HLMDL we + are forced to manually position the bones of our attachnment + by iterating over them and manually setting their position in 3D-space. +*/ +string g_pbones[] = +{ + "Bip01", + "Bip01 Footsteps", + "Bip01 Pelvis", + "Bip01 L Leg", + "Bip01 L Leg1", + "Bip01 L Foot", + "Bip01 L Toe0", + "Bip01 L Toe01", + "Bip01 L Toe02", + "Dummy16", + "Bip01 R Leg", + "Bip01 R Leg1", + "Bip01 R Foot", + "Bip01 R Toe0", + "Bip01 R Toe01", + "Bip01 R Toe02", + "Dummy11", + "Bip01 Spine", + "Bip01 Spine1", + "Bip01 Spine2", + "Bip01 Spine3", + "Bip01 Neck", + "Bip01 Head", + "Dummy21", + "Dummy08", + "Bone02", + "Bone03", + "Bone04", + "Dummy05", + "Bone09", + "Bone10", + "Dummy04", + "Bone05", + "Bone06", + "Dummy03", + "Bone07", + "Bone08", + "Dummy09", + "Bone11", + "Bone12", +"Dummy10", + "Bone13", + "Bone14", + "Bone15", + "Bip01 L Arm", + "Bip01 L Arm1", + "Bip01 L Arm2", + "Bip01 L Hand", + "Bip01 L Finger0", + "Bip01 L Finger01", + "Bip01 L Finger02", + "Dummy06", + "Bip01 L Finger1", + "Bip01 L Finger11", + "Bip01 L Finger12", + "Dummy07", + "Bip01 R Arm", + "Bip01 R Arm1", + "Bip01 R Arm2", + "Bip01 R Hand", + "Bip01 R Finger0", + "Bip01 R Finger01", + "Bip01 R Finger02", + "Dummy01", + "Bip01 R Finger1", + "Bip01 R Finger11", + "Bip01 R Finger12", + "Dummy02", + "Box02", + "Bone08", + "Bone15" +}; +#endif + +/* all custom SendFlags bits we can possibly send */ enumflags { PLAYER_TOPFRAME = PLAYER_CUSTOMFIELDSTART, @@ -32,42 +115,42 @@ class player:NSClientPlayer void(void) player; /* animation */ - PREDICTED_INT(anim_top); - PREDICTED_FLOAT(anim_top_time); - PREDICTED_FLOAT(anim_top_delay); - PREDICTED_INT(anim_bottom); - PREDICTED_FLOAT(anim_bottom_time); + PREDICTED_INT(anim_top) + PREDICTED_FLOAT(anim_top_time) + PREDICTED_FLOAT(anim_top_delay) + PREDICTED_INT(anim_bottom) + PREDICTED_FLOAT(anim_bottom_time) /* ammo 1 */ - PREDICTED_INT(glock_mag); - PREDICTED_INT(mp5_mag); - PREDICTED_INT(python_mag); - PREDICTED_INT(shotgun_mag); - PREDICTED_INT(crossbow_mag); - PREDICTED_INT(rpg_mag); - PREDICTED_INT(satchel_chg); + PREDICTED_INT(glock_mag) + PREDICTED_INT(mp5_mag) + PREDICTED_INT(python_mag) + PREDICTED_INT(shotgun_mag) + PREDICTED_INT(crossbow_mag) + PREDICTED_INT(rpg_mag) + PREDICTED_INT(satchel_chg) /* ammo 2 */ - PREDICTED_INT(ammo_9mm); - PREDICTED_INT(ammo_357); - PREDICTED_INT(ammo_buckshot); - PREDICTED_INT(ammo_bolt); - PREDICTED_INT(ammo_rocket); - PREDICTED_INT(ammo_uranium); - PREDICTED_INT(ammo_handgrenade); - PREDICTED_INT(ammo_satchel); - PREDICTED_INT(ammo_tripmine); - PREDICTED_INT(ammo_snark); - PREDICTED_INT(ammo_hornet); + PREDICTED_INT(ammo_9mm) + PREDICTED_INT(ammo_357) + PREDICTED_INT(ammo_buckshot) + PREDICTED_INT(ammo_bolt) + PREDICTED_INT(ammo_rocket) + PREDICTED_INT(ammo_uranium) + PREDICTED_INT(ammo_handgrenade) + PREDICTED_INT(ammo_satchel) + PREDICTED_INT(ammo_tripmine) + PREDICTED_INT(ammo_snark) + PREDICTED_INT(ammo_hornet) /* ammo 3 */ - PREDICTED_INT(ammo_m203_grenade); - PREDICTED_INT(ammo_gauss_volume); - PREDICTED_INT(ammo_rpg_state); - PREDICTED_INT(mode_tempstate); + PREDICTED_INT(ammo_m203_grenade) + PREDICTED_INT(ammo_gauss_volume) + PREDICTED_INT(ammo_rpg_state) + PREDICTED_INT(mode_tempstate) - virtual void(void) Physics_Jump; - virtual void UpdatePlayerAnimation(void); + virtual void Physics_Jump(void); + virtual void UpdatePlayerAnimation(float); #ifdef CLIENT ////virtual void(void) draw; @@ -85,34 +168,98 @@ class player:NSClientPlayer #endif }; -#ifdef CLIENT void Animation_PlayerUpdate(player); void Animation_TimerUpdate(player, float); -#endif void -player::UpdatePlayerAnimation(void) +player::UpdatePlayerAnimation(float timelength) { -#ifdef CLIENT /* calculate our skeletal progression */ Animation_PlayerUpdate(this); /* advance animation timers */ - Animation_TimerUpdate(this, clframetime); -#endif + Animation_TimerUpdate(this, timelength); } #ifdef CLIENT -void Player_HandleWeaponModel(NSClientPlayer pp, float thirdperson); -void Player_Flashlight(NSClientPlayer); +.string oldmodel; +string Weapons_GetPlayermodel(player, int); void player::UpdatePlayerAttachments(bool visible) { - Player_Flashlight(this); + /* draw the flashlight */ + if (gflags & GF_FLASHLIGHT) { + vector src; + vector ang; + + if (entnum != player_localentnum) { + src = origin + view_ofs; + ang = v_angle; + } else { + src = pSeat->m_vecPredictedOrigin + [0,0,-8]; + ang = view_angles; + } + + makevectors(ang); + traceline(src, src + (v_forward * 8096), MOVE_NORMAL, this); + + if (serverkeyfloat("*bspversion") == BSPVER_HL) { + dynamiclight_add(trace_endpos + (v_forward * -2), 128, [1,1,1]); + } else { + float p = dynamiclight_add(src, 512, [1,1,1], 0, "textures/flashlight"); + dynamiclight_set(p, LFIELD_ANGLES, ang); + dynamiclight_set(p, LFIELD_FLAGS, 3); + } + } /* FIXME: this needs to be incorporated and simplified, now that we can handle it all in-class */ - if (visible) - Player_HandleWeaponModel(this, visible ? 1:0); + if (!visible) + return; + + /* what's the current weapon model supposed to be anyway? */ + p_model.oldmodel = Weapons_GetPlayermodel(this, activeweapon); + + /* we changed weapons, update skeletonindex */ + if (p_model.model != p_model.oldmodel) { + /* free memory */ + if (p_model.skeletonindex) + skel_delete(p_model.skeletonindex); + + /* set the new model and mark us updated */ + setmodel(p_model, p_model.oldmodel); + p_model.model = p_model.oldmodel; + + /* set the new skeletonindex */ + p_model.skeletonindex = skel_create(p_model.modelindex); + + /* hack this thing in here FIXME: this should be done when popping in/out of a pvs */ + if (autocvar(cl_himodels, 1, "Use high-quality thisayer models over lower-definition ones")) + setcustomskin(this, "", "geomset 0 2\n"); + else + setcustomskin(this, "", "geomset 0 1\n"); + } + + /* follow thisayer at all times */ + setorigin(p_model, origin); + p_model.angles = angles; + skel_build(p_model.skeletonindex, p_model, p_model.modelindex,0, 0, -1); + + /* we have to loop through all valid bones of the weapon model and match them + * to the thisayer one */ + for (float i = 0; i < g_pbones.length; i++) { + vector bpos; + float pbone = gettagindex(this, g_pbones[i]); + float wbone = gettagindex(p_model, g_pbones[i]); + + /* if the bone doesn't ignore in either skeletal mesh, ignore */ + if (wbone <= 0 || pbone <= 0) + continue; + + bpos = gettaginfo(this, pbone); + + /* the most expensive bit */ + skel_set_bone_world(p_model, wbone, bpos, v_forward, v_right, v_up); + } } void Weapons_AmmoUpdate(entity); @@ -505,4 +652,31 @@ player::SendEntity(entity ePEnt, float flChanged) void player::player(void) { + anim_top = 0; + anim_top_time = 0; + anim_top_delay = 0; + anim_bottom = 0; + anim_bottom_time = 0; + glock_mag = 0; + mp5_mag = 0; + python_mag = 0; + shotgun_mag = 0; + crossbow_mag = 0; + rpg_mag = 0; + satchel_chg = 0; + ammo_9mm = 0; + ammo_357 = 0; + ammo_buckshot = 0; + ammo_bolt = 0; + ammo_rocket = 0; + ammo_uranium = 0; + ammo_handgrenade = 0; + ammo_satchel = 0; + ammo_tripmine = 0; + ammo_snark = 0; + ammo_hornet = 0; + ammo_m203_grenade = 0; + ammo_gauss_volume = 0; + ammo_rpg_state = 0; + mode_tempstate = 0; } diff --git a/src/shared/w_crowbar.qc b/src/shared/w_crowbar.qc index 9eebcd3..cd56f81 100644 --- a/src/shared/w_crowbar.qc +++ b/src/shared/w_crowbar.qc @@ -150,6 +150,7 @@ w_crowbar_primary(player pl) } } else { Sound_Play(pl, CHAN_WEAPON, "weapon_crowbar.hit"); + DecalGroups_Place("Impact.Shot", trace_endpos + (v_forward * -2)); } #endif } diff --git a/zpak001.pk3dir/scripts/decals.txt b/zpak001.pk3dir/scripts/decals.txt index 46c513c..d1ccea5 100644 --- a/zpak001.pk3dir/scripts/decals.txt +++ b/zpak001.pk3dir/scripts/decals.txt @@ -3,8 +3,8 @@ Impact.Shot "{shot1" "1" "{shot2" "1" "{shot3" "1" - "{shot3" "1" - "{shot3" "1" + "{shot4" "1" + "{shot5" "1" } Impact.BigShot diff --git a/zpak001.pk3dir/scripts/propdata.txt b/zpak001.pk3dir/scripts/propdata.txt new file mode 100644 index 0000000..540e3e4 --- /dev/null +++ b/zpak001.pk3dir/scripts/propdata.txt @@ -0,0 +1,76 @@ +"PropData.txt" +{ + "gs_material_glass" + { + "breakable_model" "gibs_glass" + } + "gs_material_wood" + { + "breakable_model" "gibs_wood" + } + "gs_material_metal" + { + "breakable_model" "gibs_metalplate" + } + "gs_material_flesh" + { + "breakable_model" "gibs_flesh" + } + "gs_material_cinderblock" + { + "breakable_model" "gibs_cinder" + } + "gs_material_tile" + { + "breakable_model" "gibs_ceiling" + } + "gs_material_computer" + { + "breakable_model" "gibs_computer" + } + "gs_material_unbreakableglass" + { + "breakable_model" "gibs_glass" + } + "gs_material_rocks" + { + "breakable_model" "gibs_rock" + } + + + "BreakableModels" + { + "gibs_glass" + { + "models/glassgibs.mdl#submodels=8#rendermode=5" "5.0" + } + "gibs_wood" + { + "models/woodgibs.mdl#submodels=3" "5.0" + } + "gibs_metalplate" + { + "models/metalplategibs.mdl#submodels=13" "5.0" + } + "gibs_flesh" + { + "models/fleshgibs.mdl#submodels=4" "5.0" + } + "gibs_ceiling" + { + "models/ceilinggibs.mdl#submodels=4" "5.0" + } + "gibs_computer" + { + "models/computergibs.mdl#submodels=15" "5.0" + } + "gibs_rock" + { + "models/rockgibs.mdl#submodels=3" "5.0" + } + "gibs_cinder" + { + "models/cindergibs.mdl#submodels=9" "5.0" + } + } +} diff --git a/zpak001.pk3dir/scripts/surfaceproperties.txt b/zpak001.pk3dir/scripts/surfaceproperties.txt index 6ac9e7c..25d502b 100644 --- a/zpak001.pk3dir/scripts/surfaceproperties.txt +++ b/zpak001.pk3dir/scripts/surfaceproperties.txt @@ -33,6 +33,14 @@ gs_material_metal stepright "step_metal.right" } +gs_material_ladder +{ + part_bulletimpact "impact_default.main" + bulletimpact "sfx_impact.metal" + stepleft "step_ladder.left" + stepright "step_ladder.right" +} + gs_material_flesh { gamematerial F