Major work on item_tfgoal and info_tfgoal. We now got 2fort style maps
working functionally. A lot is still missing however. Especially visual fluff.
This commit is contained in:
parent
cd750cd5d8
commit
a0a65b9843
14 changed files with 1222 additions and 315 deletions
|
@ -16,6 +16,8 @@
|
|||
|
||||
class TFCGameRules:CGameRules
|
||||
{
|
||||
void(void) TFCGameRules;
|
||||
|
||||
virtual void(base_player) PlayerConnect;
|
||||
virtual void(base_player) PlayerDisconnect;
|
||||
virtual void(base_player) PlayerPostFrame;
|
||||
|
|
|
@ -82,3 +82,13 @@ TFCGameRules::PlayerSpawn(base_player pp)
|
|||
forceinfokey(pl, "*spec", "2");
|
||||
Spawn_ObserverCam(pl);
|
||||
}
|
||||
|
||||
void
|
||||
TFCGameRules::TFCGameRules(void)
|
||||
{
|
||||
forceinfokey(world, "teams", "2");
|
||||
forceinfokey(world, "team_1", "Blue");
|
||||
forceinfokey(world, "teamscore_1", "0");
|
||||
forceinfokey(world, "team_2", "Red");
|
||||
forceinfokey(world, "teamscore_2", "0");
|
||||
}
|
||||
|
|
|
@ -14,32 +14,192 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* A lot of this has been sourced and verified via:
|
||||
* http://www.bspquakeeditor.com/archive/planetfortress_com_factory/files/tfortmap.txt
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TFGOAL_ACTIVE, /* cannot be touched by a player */
|
||||
TFGOAL_INACTIVE, /* will become ACTIVE when the toucher meets the criteria */
|
||||
TFGOAL_REMOVED /* cannot be touched by players at all, only other events */
|
||||
} tfgoal_state;
|
||||
|
||||
/* conditions under which the goal will activate */
|
||||
typedef enumflags
|
||||
{
|
||||
TFACT_NONE,
|
||||
TFACT_TOUCH,
|
||||
TFACT_DETPACK,
|
||||
TFACT_FAILURE,
|
||||
TFACT_DROPTOGROUND = 2048
|
||||
} tfgoal_activation;
|
||||
|
||||
typedef enumflags
|
||||
{
|
||||
TFEF_ACTIVATOR, /* single activator */
|
||||
TFEF_ACTTEAM, /* activators team */
|
||||
TFEF_NONACTTEAM, /* everyone elses but activators team */
|
||||
TFEF_NONACTIVATORS, /* everyone but the activator */
|
||||
TFEF_WALLOBSTRUCT, /* everyone not tracelineable? */
|
||||
TFEF_PVS, /* everyone not in the same pvs? */
|
||||
TFEF_CHECK, /* no idea */
|
||||
} tfgoal_effects;
|
||||
|
||||
typedef enumflags
|
||||
{
|
||||
TFRESULT_NONE = 0,
|
||||
TFRESULT_REMOVE = 1, /* remove right away */
|
||||
TFRESULT_SUBGOAL_MODS = 2,
|
||||
TFRESULT_SCORES = 4,
|
||||
TFRESULT_SUBGOAL_NOMODS = 8,
|
||||
TFRESULT_NODISGUISE = 16,
|
||||
TFRESULT_FORCERESPAWN = 32,
|
||||
TFRESULT_REMOVE_BUILDINGS = 64
|
||||
} tfgoal_result;
|
||||
|
||||
/* point entity version */
|
||||
class info_tfgoal:CBaseTrigger
|
||||
{
|
||||
string m_strName;
|
||||
string m_strSound;
|
||||
string m_strActivatedSound;
|
||||
|
||||
int m_iGoalID; /* goal identifer */
|
||||
int m_iGoalGroupID; /* goal group ID */
|
||||
|
||||
tfgoal_state m_tfgState;
|
||||
tfgoal_activation m_tfgActivation;
|
||||
tfgoal_effects m_tfgEffects;
|
||||
tfgoal_result m_tfgResult;
|
||||
player m_Activator;
|
||||
|
||||
float m_dMustCarry; /* player must carry item of this ID */
|
||||
float m_dRespawn; /* respawn after num seconds on TFRESULT_REMOVE */
|
||||
|
||||
float m_dTeamBlueGain;
|
||||
float m_dTeamRedGain;
|
||||
float m_dTeamYellowGain;
|
||||
float m_dTeamGreenGain;
|
||||
float m_dScore; /* score to be added to the activators' team score */
|
||||
int m_iTeam; /* which team this belongs to */
|
||||
|
||||
int m_iHealth;
|
||||
int m_iArmor;
|
||||
int m_iShells;
|
||||
int m_iNails;
|
||||
int m_iCells;
|
||||
int m_iMedikit;
|
||||
int m_iRockets;
|
||||
int m_iDetpack;
|
||||
|
||||
void(void) info_tfgoal;
|
||||
virtual void(void) touch;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(string, string) SpawnKey;
|
||||
};
|
||||
|
||||
void
|
||||
info_tfgoal::touch(void)
|
||||
{
|
||||
item_tfgoal findme = __NULL__;
|
||||
|
||||
if (other.classname != "player") {
|
||||
return;
|
||||
}
|
||||
player pl = (player)other;
|
||||
|
||||
sound(this, CHAN_ITEM, m_strSound, 1.0f, ATTN_NORM);
|
||||
/* check for state */
|
||||
if (m_tfgState != TFGOAL_INACTIVE)
|
||||
return;
|
||||
|
||||
/* check for team eligibility */
|
||||
if (m_iTeam)
|
||||
if (other.team != m_iTeam)
|
||||
return;
|
||||
|
||||
/* check for the must-have carry */
|
||||
if (m_dMustCarry) {
|
||||
item_tfgoal findme = __NULL__;
|
||||
|
||||
/* find the needle in the haystack */
|
||||
for (entity e = world; (e = find(e, ::classname, "item_tfgoal"));) {
|
||||
item_tfgoal a = (item_tfgoal)e;
|
||||
|
||||
if (a.m_dItemID == m_dMustCarry)
|
||||
findme = a;
|
||||
}
|
||||
|
||||
if (!findme) {
|
||||
printf("can't find the pickup\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (findme.solid != SOLID_NOT) {
|
||||
printf("the item is not picked up.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (findme.m_eActivator != pl) {
|
||||
printf("you are not the items activator.\n");
|
||||
return;
|
||||
} else {
|
||||
/* unset the activator and make it reappear */
|
||||
findme.Respawn();
|
||||
}
|
||||
}
|
||||
|
||||
sound(this, CHAN_ITEM, m_strActivatedSound, 1.0f, ATTN_NORM);
|
||||
Logging_Pickup(other, this, m_strName);
|
||||
|
||||
if (cvar("sv_playerslots") == 1) {
|
||||
remove(self);
|
||||
} else {
|
||||
/* here we increase/decrease funstuff */
|
||||
pl.health += m_iHealth;
|
||||
pl.armor += m_iArmor;
|
||||
pl.m_iAmmoShells += m_iShells;
|
||||
pl.m_iAmmoNails += m_iNails;
|
||||
pl.m_iAmmoCells += m_iCells;
|
||||
pl.m_iAmmoRockets += m_iRockets;
|
||||
pl.m_iAmmoMedikit += m_iMedikit;
|
||||
pl.m_iAmmoDetpack += m_iDetpack;
|
||||
|
||||
/* clamp */
|
||||
pl.health = bound(0, pl.health, pl.m_iMaxHealth);
|
||||
pl.armor = bound(0, pl.armor, pl.m_iMaxArmor);
|
||||
pl.m_iAmmoShells = bound(0, pl.m_iAmmoShells, pl.m_iMaxShells);
|
||||
pl.m_iAmmoNails = bound(0, pl.m_iAmmoNails, pl.m_iMaxNails);
|
||||
pl.m_iAmmoCells = bound(0, pl.m_iAmmoCells, pl.m_iMaxCells);
|
||||
pl.m_iAmmoRockets = bound(0, pl.m_iAmmoRockets, pl.m_iMaxRockets);
|
||||
|
||||
pl.frags += frags;
|
||||
|
||||
string ts;
|
||||
if (m_dScore) {
|
||||
ts = sprintf("teamscore_%i", m_iTeam);
|
||||
forceinfokey(world, ts, sprintf("%d", serverkeyfloat(ts) + m_dScore));
|
||||
}
|
||||
if (m_dTeamBlueGain) {
|
||||
ts = "teamscore_1";
|
||||
forceinfokey(world, ts, sprintf("%d", serverkeyfloat(ts) + m_dTeamBlueGain));
|
||||
}
|
||||
if (m_dTeamRedGain) {
|
||||
ts = "teamscore_2";
|
||||
forceinfokey(world, ts, sprintf("%d", serverkeyfloat(ts) + m_dTeamRedGain));
|
||||
}
|
||||
if (m_dTeamYellowGain) {
|
||||
ts = "teamscore_3";
|
||||
forceinfokey(world, ts, sprintf("%d", serverkeyfloat(ts) + m_dTeamYellowGain));
|
||||
}
|
||||
if (m_dTeamGreenGain) {
|
||||
ts = "teamscore_4";
|
||||
forceinfokey(world, ts, sprintf("%d", serverkeyfloat(ts) + m_dTeamGreenGain));
|
||||
}
|
||||
|
||||
/* remove? */
|
||||
if (m_tfgResult & TFRESULT_REMOVE) {
|
||||
Hide();
|
||||
think = Respawn;
|
||||
nextthink = time + 30.0f;
|
||||
if (m_dRespawn) {
|
||||
think = Respawn;
|
||||
nextthink = time + m_dRespawn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,29 +213,129 @@ info_tfgoal::Respawn(void)
|
|||
SetOrigin(m_oldOrigin);
|
||||
}
|
||||
|
||||
void
|
||||
info_tfgoal::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "netname":
|
||||
netname = strValue;
|
||||
break;
|
||||
case "noise":
|
||||
m_strActivatedSound = strValue;
|
||||
break;
|
||||
case "mdl":
|
||||
model = strValue;
|
||||
break;
|
||||
case "goal_state":
|
||||
m_tfgState = stof(strValue);
|
||||
break;
|
||||
case "g_a":
|
||||
m_tfgActivation = stof(strValue);
|
||||
break;
|
||||
case "g_e":
|
||||
m_tfgEffects = stof(strValue);
|
||||
break;
|
||||
case "goal_result":
|
||||
m_tfgResult = stof(strValue);
|
||||
break;
|
||||
case "items_allowed":
|
||||
m_dMustCarry = stof(strValue);
|
||||
break;
|
||||
case "team_no":
|
||||
m_iTeam = stoi(strValue);
|
||||
break;
|
||||
case "count":
|
||||
m_dScore = stof(strValue);
|
||||
break;
|
||||
case "wait":
|
||||
m_dRespawn = stof(strValue);
|
||||
break;
|
||||
case "increase_team1":
|
||||
m_dTeamBlueGain = stof(strValue);
|
||||
break;
|
||||
case "increase_team2":
|
||||
m_dTeamRedGain = stof(strValue);
|
||||
break;
|
||||
case "increase_team3":
|
||||
m_dTeamYellowGain = stof(strValue);
|
||||
break;
|
||||
case "increase_team4":
|
||||
m_dTeamGreenGain = stof(strValue);
|
||||
break;
|
||||
/* AP manipulators */
|
||||
case "health":
|
||||
m_iHealth = stoi(strValue);
|
||||
break;
|
||||
case "armor":
|
||||
m_iArmor = stoi(strValue);
|
||||
break;
|
||||
case "ammo_shells":
|
||||
m_iShells = stoi(strValue);
|
||||
break;
|
||||
case "ammo_nails":
|
||||
m_iNails = stoi(strValue);
|
||||
break;
|
||||
case "ammo_rockets":
|
||||
m_iRockets = stoi(strValue);
|
||||
break;
|
||||
case "ammo_cells":
|
||||
m_iCells = stoi(strValue);
|
||||
break;
|
||||
case "ammo_medikit":
|
||||
m_iMedikit = stoi(strValue);
|
||||
break;
|
||||
default:
|
||||
CBaseTrigger::SpawnKey(strKey, strValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
info_tfgoal::info_tfgoal(void)
|
||||
{
|
||||
m_tfgState = TFGOAL_INACTIVE;
|
||||
m_tfgResult = TFRESULT_REMOVE;
|
||||
|
||||
for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) {
|
||||
switch (argv(i)) {
|
||||
case "netname":
|
||||
m_strSound = argv(i+1);
|
||||
netname = __NULL__;
|
||||
break;
|
||||
case "noise":
|
||||
m_strSound = argv(i+1);
|
||||
break;
|
||||
case "mdl":
|
||||
model = argv(i+1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SpawnKey(argv(i), argv(i+1));
|
||||
}
|
||||
precache_sound(m_strSound);
|
||||
|
||||
precache_sound(m_strActivatedSound);
|
||||
|
||||
CBaseEntity::CBaseEntity();
|
||||
info_tfgoal::Respawn();
|
||||
}
|
||||
|
||||
CLASSEXPORT(i_t_g, info_tfgoal)
|
||||
class i_t_g:info_tfgoal
|
||||
{
|
||||
void(void) i_t_g;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void
|
||||
i_t_g::Respawn(void)
|
||||
{
|
||||
solid = SOLID_BSPTRIGGER;
|
||||
movetype = MOVETYPE_NONE;
|
||||
SetModel(m_oldModel);
|
||||
SetOrigin(m_oldOrigin);
|
||||
}
|
||||
|
||||
void
|
||||
i_t_g::i_t_g(void)
|
||||
{
|
||||
classname = "info_tfgoal";
|
||||
|
||||
m_tfgState = TFGOAL_INACTIVE;
|
||||
m_tfgResult = TFRESULT_NONE;
|
||||
|
||||
for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) {
|
||||
SpawnKey(argv(i), argv(i+1));
|
||||
}
|
||||
|
||||
|
||||
CBaseEntity::CBaseEntity();
|
||||
|
||||
precache_sound(m_strActivatedSound);
|
||||
Respawn();
|
||||
}
|
||||
|
|
|
@ -16,7 +16,14 @@
|
|||
|
||||
class item_tfgoal:CBaseTrigger
|
||||
{
|
||||
float m_dItemID;
|
||||
|
||||
int m_iTeamUses;
|
||||
string m_strSound;
|
||||
string m_voxTeam;
|
||||
string m_voxOtherTeam;
|
||||
string m_voxActivator;
|
||||
player m_eActivator;
|
||||
|
||||
void(void) item_tfgoal;
|
||||
virtual void(void) touch;
|
||||
|
@ -30,12 +37,35 @@ item_tfgoal::touch(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (cvar("sv_playerslots") == 1) {
|
||||
remove(self);
|
||||
} else {
|
||||
Hide();
|
||||
think = Respawn;
|
||||
nextthink = time + 20.0f;
|
||||
player pl = (player)other;
|
||||
|
||||
/* team filter */
|
||||
if (m_iTeamUses)
|
||||
if (m_iTeamUses != pl.team)
|
||||
return;
|
||||
|
||||
Hide();
|
||||
pl.g_items |= ITEM_GOALITEM;
|
||||
m_eActivator = pl;
|
||||
|
||||
sound(this, CHAN_ITEM, m_strSound, 1.0f, ATTN_NONE);
|
||||
|
||||
/* broadcast via VOX that this was taken from us */
|
||||
for (entity e = world; (e = find(e, ::classname, "player")); ) {
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_CHAT_VOX);
|
||||
|
||||
if (e.team != m_iTeamUses) {
|
||||
WriteString(MSG_MULTICAST, m_voxOtherTeam);
|
||||
} else {
|
||||
if (e == pl)
|
||||
WriteString(MSG_MULTICAST, m_voxActivator);
|
||||
else
|
||||
WriteString(MSG_MULTICAST, m_voxTeam);
|
||||
}
|
||||
|
||||
msg_entity = e;
|
||||
multicast([0,0,0], MULTICAST_ONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,6 +77,7 @@ item_tfgoal::Respawn(void)
|
|||
SetModel(m_oldModel);
|
||||
setsize(this, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
SetOrigin(m_oldOrigin);
|
||||
m_eActivator = __NULL__;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -60,6 +91,21 @@ item_tfgoal::item_tfgoal(void)
|
|||
case "mdl":
|
||||
model = argv(i+1);
|
||||
break;
|
||||
case "goal_no":
|
||||
m_dItemID = stof(argv(i+1));
|
||||
break;
|
||||
case "team_no":
|
||||
m_iTeamUses = stoi(argv(i+1));
|
||||
break;
|
||||
case "AP_speak":
|
||||
m_voxActivator = argv(i+1);
|
||||
break;
|
||||
case "team_speak":
|
||||
m_voxTeam = argv(i+1);
|
||||
break;
|
||||
case "non_team_speak":
|
||||
m_voxOtherTeam = argv(i+1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ defs.h
|
|||
|
||||
../../../valve/src/server/items.qc
|
||||
info_player_teamspawn.qc
|
||||
info_tfgoal.qc
|
||||
item_tfgoal.qc
|
||||
info_tfgoal.qc
|
||||
|
||||
gamerules.qc
|
||||
../../../valve/src/server/client.qc
|
||||
|
|
|
@ -80,6 +80,7 @@ CSEv_TeamJoin_f(float f)
|
|||
forceinfokey(pl, "bottomcolor", "0x3bff00");
|
||||
}
|
||||
|
||||
forceinfokey(pl, "*team", ftos(pl.team));
|
||||
pl.model = g_teammodels[f];
|
||||
setmodel(pl, pl.model);
|
||||
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
|
@ -119,6 +120,18 @@ CSEv_TeamJoin_f(float f)
|
|||
Weapons_AddItem(pl, WEAPON_CROWBAR, -1);
|
||||
Weapons_AddItem(pl, WEAPON_SBS, -1);
|
||||
Weapons_AddItem(pl, WEAPON_NAILGUN, -1);
|
||||
pl.m_iAmmoShells = 17;
|
||||
pl.m_iAmmoNails = 100;
|
||||
|
||||
pl.m_iMaxHealth = 75;
|
||||
pl.m_iMaxArmor = 50;
|
||||
pl.health = pl.m_iMaxHealth;
|
||||
pl.armor = 25;
|
||||
|
||||
pl.m_iMaxShells = 50;
|
||||
pl.m_iMaxNails = 200;
|
||||
pl.m_iMaxCells = 100;
|
||||
pl.m_iMaxRockets = 25;
|
||||
env_message_single(pl, "HELP_SCOUT");
|
||||
break;
|
||||
case CLASS_SNIPER:
|
||||
|
@ -126,6 +139,18 @@ CSEv_TeamJoin_f(float f)
|
|||
Weapons_AddItem(pl, WEAPON_SNIPER, -1);
|
||||
Weapons_AddItem(pl, WEAPON_AUTORIFLE, -1);
|
||||
Weapons_AddItem(pl, WEAPON_NAILGUN, -1);
|
||||
pl.m_iAmmoShells = 60; /* sniper rifles use shells */
|
||||
pl.m_iAmmoNails = 50;
|
||||
|
||||
pl.m_iMaxHealth = 90;
|
||||
pl.m_iMaxArmor = 50;
|
||||
pl.health = pl.m_iMaxHealth;
|
||||
pl.armor = 0;
|
||||
|
||||
pl.m_iMaxShells = 75;
|
||||
pl.m_iMaxNails = 100;
|
||||
pl.m_iMaxCells = 50;
|
||||
pl.m_iMaxRockets = 25;
|
||||
env_message_single(pl, "HELP_SNIPER");
|
||||
break;
|
||||
case CLASS_SOLDIER:
|
||||
|
@ -133,6 +158,18 @@ CSEv_TeamJoin_f(float f)
|
|||
Weapons_AddItem(pl, WEAPON_SBS, -1);
|
||||
Weapons_AddItem(pl, WEAPON_DBS, -1);
|
||||
Weapons_AddItem(pl, WEAPON_RPG, -1);
|
||||
pl.m_iAmmoShells = 26;
|
||||
pl.m_iAmmoRockets = 6;
|
||||
|
||||
pl.m_iMaxHealth = 100;
|
||||
pl.m_iMaxArmor = 200;
|
||||
pl.health = pl.m_iMaxHealth;
|
||||
pl.armor = 100;
|
||||
|
||||
pl.m_iMaxShells = 100;
|
||||
pl.m_iMaxNails = 100;
|
||||
pl.m_iMaxCells = 50;
|
||||
pl.m_iMaxRockets = 50;
|
||||
env_message_single(pl, "HELP_SOLDIER");
|
||||
break;
|
||||
case CLASS_DEMO:
|
||||
|
@ -140,6 +177,18 @@ CSEv_TeamJoin_f(float f)
|
|||
Weapons_AddItem(pl, WEAPON_SBS, -1);
|
||||
Weapons_AddItem(pl, WEAPON_GLAUNCHER, -1);
|
||||
Weapons_AddItem(pl, WEAPON_PIPEBOMB, -1);
|
||||
pl.m_iAmmoShells = 22;
|
||||
pl.m_iAmmoRockets = 14;
|
||||
|
||||
pl.m_iMaxHealth = 90;
|
||||
pl.m_iMaxArmor = 100;
|
||||
pl.health = pl.m_iMaxHealth;
|
||||
pl.armor = 50;
|
||||
|
||||
pl.m_iMaxShells = 75;
|
||||
pl.m_iMaxNails = 50;
|
||||
pl.m_iMaxCells = 50;
|
||||
pl.m_iMaxRockets = 50;
|
||||
env_message_single(pl, "HELP_DEMOMAN");
|
||||
break;
|
||||
case CLASS_MEDIC:
|
||||
|
@ -147,6 +196,18 @@ CSEv_TeamJoin_f(float f)
|
|||
Weapons_AddItem(pl, WEAPON_SBS, -1);
|
||||
Weapons_AddItem(pl, WEAPON_DBS, -1);
|
||||
Weapons_AddItem(pl, WEAPON_SUPERNAIL, -1);
|
||||
pl.m_iAmmoShells = 26;
|
||||
pl.m_iAmmoNails = 50;
|
||||
|
||||
pl.m_iMaxHealth = 90;
|
||||
pl.m_iMaxArmor = 100;
|
||||
pl.health = pl.m_iMaxHealth;
|
||||
pl.armor = 50;
|
||||
|
||||
pl.m_iMaxShells = 75;
|
||||
pl.m_iMaxNails = 150;
|
||||
pl.m_iMaxCells = 50;
|
||||
pl.m_iMaxRockets = 25;
|
||||
env_message_single(pl, "HELP_MEDIC");
|
||||
break;
|
||||
case CLASS_HVYWEAPON:
|
||||
|
@ -154,6 +215,17 @@ CSEv_TeamJoin_f(float f)
|
|||
Weapons_AddItem(pl, WEAPON_SBS, -1);
|
||||
Weapons_AddItem(pl, WEAPON_DBS, -1);
|
||||
Weapons_AddItem(pl, WEAPON_ASSCAN, -1);
|
||||
pl.m_iAmmoShells = 176; /* all of the heavy's weapons use shells */
|
||||
|
||||
pl.m_iMaxHealth = 100;
|
||||
pl.m_iMaxArmor = 250;
|
||||
pl.health = pl.m_iMaxHealth;
|
||||
pl.armor = 150;
|
||||
|
||||
pl.m_iMaxShells = 200;
|
||||
pl.m_iMaxNails = 200;
|
||||
pl.m_iMaxCells = 50;
|
||||
pl.m_iMaxRockets = 25;
|
||||
env_message_single(pl, "HELP_HWGUY");
|
||||
break;
|
||||
case CLASS_PYRO:
|
||||
|
@ -161,6 +233,19 @@ CSEv_TeamJoin_f(float f)
|
|||
Weapons_AddItem(pl, WEAPON_SBS, -1);
|
||||
Weapons_AddItem(pl, WEAPON_FLAMER, -1);
|
||||
Weapons_AddItem(pl, WEAPON_INCENDIARY, -1);
|
||||
pl.m_iAmmoShells = 12;
|
||||
pl.m_iAmmoCells = 120;
|
||||
pl.m_iAmmoRockets = 5;
|
||||
|
||||
pl.m_iMaxHealth = 100;
|
||||
pl.m_iMaxArmor = 150;
|
||||
pl.health = pl.m_iMaxHealth;
|
||||
pl.armor = 50;
|
||||
|
||||
pl.m_iMaxShells = 40;
|
||||
pl.m_iMaxNails = 50;
|
||||
pl.m_iMaxCells = 200;
|
||||
pl.m_iMaxRockets = 60;
|
||||
env_message_single(pl, "HELP_PYRO");
|
||||
break;
|
||||
case CLASS_SPY:
|
||||
|
@ -168,12 +253,37 @@ CSEv_TeamJoin_f(float f)
|
|||
Weapons_AddItem(pl, WEAPON_TRANQUIL, -1);
|
||||
Weapons_AddItem(pl, WEAPON_DBS, -1);
|
||||
Weapons_AddItem(pl, WEAPON_NAILGUN, -1);
|
||||
pl.m_iAmmoShells = 24; /* tranquil and dbs use shells */
|
||||
pl.m_iAmmoNails = 50;
|
||||
|
||||
pl.m_iMaxHealth = 90;
|
||||
pl.m_iMaxArmor = 100;
|
||||
pl.health = pl.m_iMaxHealth;
|
||||
pl.armor = 25;
|
||||
|
||||
pl.m_iMaxShells = 40;
|
||||
pl.m_iMaxNails = 50;
|
||||
pl.m_iMaxCells = 30;
|
||||
pl.m_iMaxRockets = 15;
|
||||
env_message_single(pl, "HELP_SPY");
|
||||
break;
|
||||
case CLASS_ENGINEER:
|
||||
Weapons_AddItem(pl, WEAPON_WRENCH, -1);
|
||||
Weapons_AddItem(pl, WEAPON_RAILGUN, -1);
|
||||
Weapons_AddItem(pl, WEAPON_DBS, -1);
|
||||
pl.m_iAmmoCells = 100;
|
||||
pl.m_iAmmoNails = 25;
|
||||
pl.m_iAmmoShells = 4;
|
||||
|
||||
pl.m_iMaxHealth = 80;
|
||||
pl.m_iMaxArmor = 50;
|
||||
pl.health = pl.m_iMaxHealth;
|
||||
pl.armor = 25;
|
||||
|
||||
pl.m_iMaxShells = 50;
|
||||
pl.m_iMaxNails = 50;
|
||||
pl.m_iMaxCells = 200;
|
||||
pl.m_iMaxRockets = 30;
|
||||
env_message_single(pl, "HELP_ENGINEER");
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#includelist
|
||||
../../../valve/src/shared/flags.h
|
||||
../../../valve/src/shared/player.qc
|
||||
player.qc
|
||||
../../../base/src/shared/weapon_common.h
|
||||
../../../valve/src/shared/animations.h
|
||||
../../../valve/src/shared/animations.qc
|
||||
|
@ -16,6 +16,13 @@
|
|||
|
||||
items.h
|
||||
weapons.h
|
||||
|
||||
../../../base/src/shared/weapon_basesemi.qc
|
||||
../../../base/src/shared/weapon_basemelee.qc
|
||||
../../../base/src/shared/weapon_baseshotgun.qc
|
||||
../../../base/src/shared/weapon_baseprojectile.qc
|
||||
../../../base/src/shared/weapon_baseautomatic.qc
|
||||
|
||||
w_asscan.qc
|
||||
w_autorifle.qc
|
||||
w_crowbar.qc
|
||||
|
|
|
@ -47,4 +47,4 @@
|
|||
#define ITEM_UNUSED29 0x10000000
|
||||
#define ITEM_UNUSED30 0x20000000
|
||||
#define ITEM_UNUSED31 0x40000000
|
||||
#define ITEM_UNUSED32 0x80000000
|
||||
#define ITEM_GOALITEM 0x80000000
|
||||
|
|
340
src/shared/player.qc
Normal file
340
src/shared/player.qc
Normal file
|
@ -0,0 +1,340 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* all potential SendFlags bits we can possibly send */
|
||||
enumflags
|
||||
{
|
||||
PLAYER_KEEPALIVE,
|
||||
PLAYER_MODELINDEX,
|
||||
PLAYER_ORIGIN,
|
||||
PLAYER_ORIGIN_Z,
|
||||
PLAYER_ANGLES_X,
|
||||
PLAYER_ANGLES_Y,
|
||||
PLAYER_COLORMAP,
|
||||
PLAYER_VELOCITY,
|
||||
PLAYER_VELOCITY_Z,
|
||||
PLAYER_FLAGS,
|
||||
PLAYER_WEAPON,
|
||||
PLAYER_ITEMS,
|
||||
PLAYER_HEALTH,
|
||||
PLAYER_ARMOR,
|
||||
PLAYER_MOVETYPE,
|
||||
PLAYER_VIEWOFS,
|
||||
PLAYER_TOPFRAME,
|
||||
PLAYER_BOTTOMFRAME,
|
||||
PLAYER_AMMO1,
|
||||
PLAYER_AMMO2,
|
||||
PLAYER_AMMO3,
|
||||
PLAYER_UNUSED1,
|
||||
PLAYER_UNUSED2
|
||||
};
|
||||
|
||||
noref int input_sequence;
|
||||
class player:base_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);
|
||||
|
||||
/* ammo 1 */
|
||||
PREDICTED_INT(mag_sbs);
|
||||
PREDICTED_INT(mag_dbs);
|
||||
PREDICTED_INT(mag_rpg);
|
||||
|
||||
/* ammo 2 */
|
||||
PREDICTED_INT(m_iAmmoRockets);
|
||||
PREDICTED_INT(m_iAmmoNails);
|
||||
PREDICTED_INT(m_iAmmoCells);
|
||||
PREDICTED_INT(m_iAmmoShells);
|
||||
PREDICTED_INT(m_iAmmoDetpack);
|
||||
PREDICTED_INT(m_iAmmoMedikit);
|
||||
|
||||
/* ammo 3 */
|
||||
PREDICTED_INT(mode_tempstate);
|
||||
|
||||
#ifdef CLIENT
|
||||
/* External model */
|
||||
entity p_model;
|
||||
int p_hand_bone;
|
||||
int p_model_bone;
|
||||
float lastweapon;
|
||||
|
||||
virtual void(void) draw;
|
||||
virtual float() predraw;
|
||||
virtual void(void) postdraw;
|
||||
virtual void(float,float) ReceiveEntity;
|
||||
virtual void(void) PredictPreFrame;
|
||||
virtual void(void) PredictPostFrame;
|
||||
#else
|
||||
int m_iMaxHealth;
|
||||
int m_iMaxArmor;
|
||||
|
||||
int m_iMaxShells;
|
||||
int m_iMaxNails;
|
||||
int m_iMaxRockets;
|
||||
int m_iMaxCells;
|
||||
int m_iMaxDetpack;
|
||||
int m_iMaxMedikit;
|
||||
|
||||
virtual void(void) EvaluateEntity;
|
||||
virtual float(entity, float) SendEntity;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CLIENT
|
||||
void Weapons_AmmoUpdate(entity);
|
||||
/*
|
||||
=================
|
||||
player::ReceiveEntity
|
||||
=================
|
||||
*/
|
||||
void
|
||||
player::ReceiveEntity(float new, float fl)
|
||||
{
|
||||
/* the generic client attributes */
|
||||
base_player::ReceiveEntity(new, fl);
|
||||
|
||||
/* animation */
|
||||
if (fl & PLAYER_TOPFRAME) {
|
||||
anim_top = readbyte();
|
||||
anim_top_time = readfloat();
|
||||
anim_top_delay = readfloat();
|
||||
}
|
||||
if (fl & PLAYER_BOTTOMFRAME) {
|
||||
anim_bottom = readbyte();
|
||||
anim_bottom_time = readfloat();
|
||||
}
|
||||
|
||||
if (fl & PLAYER_AMMO1) {
|
||||
mag_sbs = readbyte();
|
||||
mag_dbs = readbyte();
|
||||
mag_rpg = readbyte();
|
||||
}
|
||||
|
||||
if (fl & PLAYER_AMMO2) {
|
||||
m_iAmmoRockets = readbyte();
|
||||
m_iAmmoNails = readbyte();
|
||||
m_iAmmoCells = readbyte();
|
||||
m_iAmmoShells = readbyte();
|
||||
m_iAmmoDetpack = readbyte();
|
||||
m_iAmmoMedikit = readbyte();
|
||||
}
|
||||
|
||||
if (fl & PLAYER_AMMO3) {
|
||||
mode_tempstate = readbyte();
|
||||
}
|
||||
|
||||
if (fl & PLAYER_AMMO1 || fl & PLAYER_AMMO2 || fl & PLAYER_AMMO3)
|
||||
Weapons_AmmoUpdate(this);
|
||||
|
||||
setorigin(this, origin);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
player::PredictPostFrame
|
||||
|
||||
Save the last valid server values away in the _net variants of each field
|
||||
so we can roll them back later.
|
||||
=================
|
||||
*/
|
||||
void
|
||||
player::PredictPreFrame(void)
|
||||
{
|
||||
/* the generic client attributes */
|
||||
base_player::PredictPreFrame();
|
||||
|
||||
SAVE_STATE(anim_top);
|
||||
SAVE_STATE(anim_top_delay);
|
||||
SAVE_STATE(anim_top_time);
|
||||
SAVE_STATE(anim_bottom);
|
||||
SAVE_STATE(anim_bottom_time);
|
||||
|
||||
SAVE_STATE(mag_sbs);
|
||||
SAVE_STATE(mag_dbs);
|
||||
SAVE_STATE(mag_rpg);
|
||||
|
||||
SAVE_STATE(m_iAmmoRockets);
|
||||
SAVE_STATE(m_iAmmoNails);
|
||||
SAVE_STATE(m_iAmmoCells);
|
||||
SAVE_STATE(m_iAmmoShells);
|
||||
SAVE_STATE(m_iAmmoDetpack);
|
||||
SAVE_STATE(m_iAmmoMedikit);
|
||||
|
||||
SAVE_STATE(mode_tempstate);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
player::PredictPostFrame
|
||||
|
||||
Where we roll back our values to the ones last sent/verified by the server.
|
||||
=================
|
||||
*/
|
||||
void
|
||||
player::PredictPostFrame(void)
|
||||
{
|
||||
/* the generic client attributes */
|
||||
base_player::PredictPostFrame();
|
||||
|
||||
ROLL_BACK(anim_top);
|
||||
ROLL_BACK(anim_top_delay);
|
||||
ROLL_BACK(anim_top_time);
|
||||
ROLL_BACK(anim_bottom);
|
||||
ROLL_BACK(anim_bottom_time);
|
||||
|
||||
ROLL_BACK(mag_sbs);
|
||||
ROLL_BACK(mag_dbs);
|
||||
ROLL_BACK(mag_rpg);
|
||||
|
||||
ROLL_BACK(m_iAmmoRockets);
|
||||
ROLL_BACK(m_iAmmoNails);
|
||||
ROLL_BACK(m_iAmmoCells);
|
||||
ROLL_BACK(m_iAmmoShells);
|
||||
ROLL_BACK(m_iAmmoDetpack);
|
||||
ROLL_BACK(m_iAmmoMedikit);
|
||||
|
||||
ROLL_BACK(mode_tempstate);
|
||||
}
|
||||
|
||||
#else
|
||||
void
|
||||
player::EvaluateEntity(void)
|
||||
{
|
||||
/* the generic client attributes */
|
||||
base_player::EvaluateEntity();
|
||||
|
||||
/* animation */
|
||||
if (ATTR_CHANGED(anim_bottom) || ATTR_CHANGED(anim_bottom_time))
|
||||
SendFlags |= PLAYER_BOTTOMFRAME;
|
||||
if (ATTR_CHANGED(anim_top) || ATTR_CHANGED(anim_top_time) || ATTR_CHANGED(anim_top_delay))
|
||||
SendFlags |= PLAYER_TOPFRAME;
|
||||
|
||||
/* ammo 1 type updates */
|
||||
if (ATTR_CHANGED(mag_sbs))
|
||||
SendFlags |= PLAYER_AMMO1;
|
||||
else if (ATTR_CHANGED(mag_dbs))
|
||||
SendFlags |= PLAYER_AMMO1;
|
||||
else if (ATTR_CHANGED(mag_rpg))
|
||||
SendFlags |= PLAYER_AMMO1;
|
||||
|
||||
/* ammo 2 type updates */
|
||||
if (ATTR_CHANGED(m_iAmmoRockets))
|
||||
SendFlags |= PLAYER_AMMO2;
|
||||
else if (ATTR_CHANGED(m_iAmmoNails))
|
||||
SendFlags |= PLAYER_AMMO2;
|
||||
else if (ATTR_CHANGED(m_iAmmoCells))
|
||||
SendFlags |= PLAYER_AMMO2;
|
||||
else if (ATTR_CHANGED(m_iAmmoShells))
|
||||
SendFlags |= PLAYER_AMMO2;
|
||||
else if (ATTR_CHANGED(m_iAmmoDetpack))
|
||||
SendFlags |= PLAYER_AMMO2;
|
||||
else if (ATTR_CHANGED(m_iAmmoMedikit))
|
||||
SendFlags |= PLAYER_AMMO2;
|
||||
|
||||
if (ATTR_CHANGED(mode_tempstate))
|
||||
SendFlags |= PLAYER_AMMO3;
|
||||
|
||||
SAVE_STATE(mag_sbs);
|
||||
SAVE_STATE(mag_dbs);
|
||||
SAVE_STATE(mag_rpg);
|
||||
|
||||
SAVE_STATE(m_iAmmoRockets);
|
||||
SAVE_STATE(m_iAmmoNails);
|
||||
SAVE_STATE(m_iAmmoCells);
|
||||
SAVE_STATE(m_iAmmoShells);
|
||||
SAVE_STATE(m_iAmmoDetpack);
|
||||
SAVE_STATE(m_iAmmoMedikit);
|
||||
|
||||
SAVE_STATE(mode_tempstate);
|
||||
|
||||
SAVE_STATE(anim_top);
|
||||
SAVE_STATE(anim_top_delay);
|
||||
SAVE_STATE(anim_top_time);
|
||||
SAVE_STATE(anim_bottom);
|
||||
SAVE_STATE(anim_bottom_time);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
player::SendEntity
|
||||
=================
|
||||
*/
|
||||
float
|
||||
player::SendEntity(entity ePEnt, float fChanged)
|
||||
{
|
||||
/* remove our entity to other clients if we're dead */
|
||||
if (health <= 0 && ePEnt != this) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* target client isn't real, they have no client-side. abandon */
|
||||
if (clienttype(ePEnt) != CLIENTTYPE_REAL) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* other players don't need to know about these attributes */
|
||||
if (ePEnt != self) {
|
||||
fChanged &= ~PLAYER_ITEMS;
|
||||
fChanged &= ~PLAYER_HEALTH;
|
||||
fChanged &= ~PLAYER_ARMOR;
|
||||
fChanged &= ~PLAYER_VIEWOFS;
|
||||
fChanged &= ~PLAYER_AMMO1;
|
||||
fChanged &= ~PLAYER_AMMO2;
|
||||
fChanged &= ~PLAYER_AMMO3;
|
||||
}
|
||||
|
||||
WriteByte(MSG_ENTITY, ENT_PLAYER);
|
||||
WriteFloat(MSG_ENTITY, fChanged);
|
||||
|
||||
/* the generic client attributes */
|
||||
base_player::SendEntity(ePEnt, fChanged);
|
||||
|
||||
if (fChanged & PLAYER_TOPFRAME) {
|
||||
WriteByte(MSG_ENTITY, anim_top);
|
||||
WriteFloat(MSG_ENTITY, anim_top_time);
|
||||
WriteFloat(MSG_ENTITY, anim_top_delay);
|
||||
}
|
||||
if (fChanged & PLAYER_BOTTOMFRAME) {
|
||||
WriteByte(MSG_ENTITY, anim_bottom);
|
||||
WriteFloat(MSG_ENTITY, anim_bottom_time);
|
||||
}
|
||||
|
||||
if (fChanged & PLAYER_AMMO1) {
|
||||
WriteByte(MSG_ENTITY, mag_sbs);
|
||||
WriteByte(MSG_ENTITY, mag_dbs);
|
||||
WriteByte(MSG_ENTITY, mag_rpg);
|
||||
}
|
||||
|
||||
if (fChanged & PLAYER_AMMO2) {
|
||||
WriteByte(MSG_ENTITY, m_iAmmoRockets);
|
||||
WriteByte(MSG_ENTITY, m_iAmmoNails);
|
||||
WriteByte(MSG_ENTITY, m_iAmmoCells);
|
||||
WriteByte(MSG_ENTITY, m_iAmmoShells);
|
||||
WriteByte(MSG_ENTITY, m_iAmmoDetpack);
|
||||
WriteByte(MSG_ENTITY, m_iAmmoMedikit);
|
||||
}
|
||||
|
||||
if (fChanged & PLAYER_AMMO3) {
|
||||
WriteByte(MSG_ENTITY, mode_tempstate);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
|
||||
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -14,6 +14,15 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*QUAKED weapon_crowbar (0 0 1) (-16 -16 0) (16 16 32)
|
||||
"model" "models/w_crowbar.mdl"
|
||||
|
||||
HALF-LIFE (1998) ENTITY
|
||||
|
||||
Crowbar Weapon
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
CBAR_IDLE,
|
||||
|
@ -30,23 +39,21 @@ enum
|
|||
void
|
||||
w_crowbar_precache(void)
|
||||
{
|
||||
precache_sound("weapons/cbar_miss1.wav");
|
||||
precache_sound("weapons/cbar_hit1.wav");
|
||||
precache_sound("weapons/cbar_hit2.wav");
|
||||
precache_sound("weapons/cbar_hitbod1.wav");
|
||||
precache_sound("weapons/cbar_hitbod2.wav");
|
||||
precache_sound("weapons/cbar_hitbod3.wav");
|
||||
precache_model("models/v_tfc_crowbar.mdl");
|
||||
#ifdef SERVER
|
||||
Sound_Precache("weapon_crowbar.hit");
|
||||
Sound_Precache("weapon_crowbar.miss");
|
||||
Sound_Precache("weapon_crowbar.hitbody");
|
||||
precache_model("models/w_crowbar.mdl");
|
||||
#else
|
||||
precache_model("models/v_crowbar.mdl");
|
||||
precache_model("models/p_crowbar.mdl");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
w_crowbar_updateammo(player pl)
|
||||
{
|
||||
#ifdef SERVER
|
||||
Weapons_UpdateAmmo(pl, __NULL__, __NULL__, __NULL__);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
string
|
||||
|
@ -69,7 +76,7 @@ w_crowbar_deathmsg(void)
|
|||
void
|
||||
w_crowbar_draw(void)
|
||||
{
|
||||
Weapons_SetModel("models/v_tfc_crowbar.mdl");
|
||||
Weapons_SetModel("models/v_crowbar.mdl");
|
||||
Weapons_ViewAnimation(CBAR_DRAW);
|
||||
}
|
||||
|
||||
|
@ -92,37 +99,39 @@ w_crowbar_primary(void)
|
|||
|
||||
Weapons_MakeVectors();
|
||||
src = pl.origin + pl.view_ofs;
|
||||
traceline(src, src + (v_forward * 32), FALSE, pl);
|
||||
|
||||
int r = (float)input_sequence % 3;
|
||||
switch (r) {
|
||||
case 0:
|
||||
anim = trace_fraction >= 1 ? CBAR_ATTACK1MISS:CBAR_ATTACK1HIT;
|
||||
break;
|
||||
case 1:
|
||||
anim = trace_fraction >= 1 ? CBAR_ATTACK2MISS:CBAR_ATTACK2HIT;
|
||||
break;
|
||||
default:
|
||||
anim = trace_fraction >= 1 ? CBAR_ATTACK3MISS:CBAR_ATTACK3HIT;
|
||||
}
|
||||
Weapons_ViewAnimation(anim);
|
||||
/* make sure we can gib corpses */
|
||||
int oldhitcontents = self.hitcontentsmaski;
|
||||
self.hitcontentsmaski = CONTENTBITS_POINTSOLID | CONTENTBIT_CORPSE;
|
||||
traceline(src, src + (v_forward * 32), FALSE, pl);
|
||||
self.hitcontentsmaski = oldhitcontents;
|
||||
|
||||
if (trace_fraction >= 1.0) {
|
||||
pl.w_attack_next = 0.5f;
|
||||
} else {
|
||||
pl.w_attack_next = 0.25f;
|
||||
}
|
||||
|
||||
pl.w_idle_next = 2.5f;
|
||||
|
||||
#ifdef SERVER
|
||||
if (pl.flags & FL_CROUCHING) {
|
||||
Animation_PlayerTop(pl, ANIM_SHOOTCROWBAR, 0.5f);
|
||||
} else {
|
||||
Animation_PlayerTop(pl, ANIM_CR_SHOOTCROWBAR, 0.42f);
|
||||
int r = (float)input_sequence % 3;
|
||||
switch (r) {
|
||||
case 0:
|
||||
Weapons_ViewAnimation(trace_fraction >= 1 ? CBAR_ATTACK1MISS:CBAR_ATTACK1HIT);
|
||||
break;
|
||||
case 1:
|
||||
Weapons_ViewAnimation(trace_fraction >= 1 ? CBAR_ATTACK2MISS:CBAR_ATTACK2HIT);
|
||||
break;
|
||||
default:
|
||||
Weapons_ViewAnimation(trace_fraction >= 1 ? CBAR_ATTACK3MISS:CBAR_ATTACK3HIT);
|
||||
}
|
||||
|
||||
sound(pl, CHAN_WEAPON, "weapons/cbar_miss1.wav", 1, ATTN_NORM);
|
||||
if (self.flags & FL_CROUCHING)
|
||||
Animation_PlayerTop(pl, ANIM_CR_SHOOTCROWBAR, 0.41f);
|
||||
else
|
||||
Animation_PlayerTop(pl, ANIM_SHOOTCROWBAR, 0.5f);
|
||||
|
||||
#ifdef SERVER
|
||||
Sound_Play(self, CHAN_WEAPON, "weapon_crowbar.miss");
|
||||
|
||||
if (trace_fraction >= 1.0) {
|
||||
return;
|
||||
|
@ -136,25 +145,12 @@ w_crowbar_primary(void)
|
|||
}
|
||||
|
||||
if (trace_ent.takedamage) {
|
||||
Damage_Apply(trace_ent, self, 10, WEAPON_CROWBAR, DMG_BLUNT);
|
||||
|
||||
if (!trace_ent.iBleeds) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.33) {
|
||||
sound(pl, 8, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM);
|
||||
} else if (random() < 0.66) {
|
||||
sound(pl, 8, "weapons/cbar_hitbod2.wav", 1, ATTN_NORM);
|
||||
} else {
|
||||
sound(pl, 8, "weapons/cbar_hitbod3.wav", 1, ATTN_NORM);
|
||||
Damage_Apply(trace_ent, pl, Skill_GetValue("plr_crowbar", 10), WEAPON_CROWBAR, DMG_BLUNT);
|
||||
if (trace_ent.iBleeds) {
|
||||
Sound_Play(self, CHAN_WEAPON, "weapon_crowbar.hitbody");
|
||||
}
|
||||
} else {
|
||||
if (random() < 0.5) {
|
||||
sound(pl, 8, "weapons/cbar_hit1.wav", 1, ATTN_NORM);
|
||||
} else {
|
||||
sound(pl, 8, "weapons/cbar_hit2.wav", 1, ATTN_NORM);
|
||||
}
|
||||
Sound_Play(self, CHAN_WEAPON, "weapon_crowbar.hit");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -186,7 +182,7 @@ w_crowbar_hudpic(int selected, vector pos, float a)
|
|||
drawsubpic(
|
||||
pos,
|
||||
[170,45],
|
||||
"sprites/640hud4.spr_0.tga",
|
||||
g_hud4_spr,
|
||||
[0,0],
|
||||
[170/256,45/256],
|
||||
g_hud_color,
|
||||
|
@ -197,7 +193,7 @@ w_crowbar_hudpic(int selected, vector pos, float a)
|
|||
drawsubpic(
|
||||
pos,
|
||||
[170,45],
|
||||
"sprites/640hud1.spr_0.tga",
|
||||
g_hud1_spr,
|
||||
[0,0],
|
||||
[170/256,45/256],
|
||||
g_hud_color,
|
||||
|
@ -214,6 +210,7 @@ weapon_t w_crowbar =
|
|||
.id = ITEM_CROWBAR,
|
||||
.slot = 0,
|
||||
.slot_pos = 0,
|
||||
.weight = 0,
|
||||
.draw = w_crowbar_draw,
|
||||
.holster = w_crowbar_holster,
|
||||
.primary = w_crowbar_primary,
|
||||
|
|
|
@ -28,14 +28,6 @@ enum
|
|||
DBS_IDLE3
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DBS_IDLE,
|
||||
DBS_RELOAD_START,
|
||||
DBS_RELOAD,
|
||||
DBS_RELOAD_END
|
||||
};
|
||||
|
||||
void
|
||||
w_dbs_precache(void)
|
||||
{
|
||||
|
@ -51,9 +43,7 @@ w_dbs_precache(void)
|
|||
void
|
||||
w_dbs_updateammo(player pl)
|
||||
{
|
||||
#ifdef SERVER
|
||||
Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_shells, __NULL__);
|
||||
#endif
|
||||
Weapons_UpdateAmmo(pl, pl.mag_dbs, pl.m_iAmmoShells, __NULL__);
|
||||
}
|
||||
|
||||
string
|
||||
|
@ -79,7 +69,7 @@ w_dbs_pickup(int new, int startammo)
|
|||
{
|
||||
#ifdef SERVER
|
||||
player pl = (player)self;
|
||||
pl.shotgun_mag = bound(0, pl.shotgun_mag + 8, 8);
|
||||
pl.mag_dbs = bound(0, pl.mag_dbs + 16, 16);
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
@ -89,10 +79,6 @@ w_dbs_draw(void)
|
|||
{
|
||||
Weapons_SetModel("models/v_tfc_shotgun.mdl");
|
||||
Weapons_ViewAnimation(DBS_DRAW);
|
||||
#ifdef SERVER
|
||||
player pl = (player)self;
|
||||
Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_shells, __NULL__);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -104,125 +90,79 @@ w_dbs_holster(void)
|
|||
void
|
||||
w_dbs_primary(void)
|
||||
{
|
||||
int s;
|
||||
player pl = (player)self;
|
||||
if (pl.w_attack_next) {
|
||||
|
||||
if (pl.mag_dbs != 1)
|
||||
s = w_baseshotgun_fire(WEAPON_DBS, player::mag_dbs, 14, 4, [0.14, 0.08, 0]);
|
||||
else
|
||||
s = w_baseshotgun_fire(WEAPON_DBS, player::mag_dbs, 6, 4, [0.14, 0.08, 0]);
|
||||
|
||||
switch (s) {
|
||||
case AUTO_FIRE_FAILED:
|
||||
return;
|
||||
break;
|
||||
case AUTO_FIRED:
|
||||
pl.mag_dbs--;
|
||||
Weapons_ViewAnimation(DBS_FIRE1);
|
||||
Weapons_ViewPunchAngle([-2,0,0]);
|
||||
//Weapons_Sound(pl, CHAN_WEAPON, "weapon_mossberg.fire");
|
||||
pl.w_attack_next = 0.7f;
|
||||
break;
|
||||
case AUTO_LAST:
|
||||
Weapons_ViewAnimation(DBS_FIRE1);
|
||||
Weapons_ViewPunchAngle([-2,0,0]);
|
||||
//Weapons_Sound(pl, CHAN_WEAPON, "weapon_mossberg.fire");
|
||||
pl.w_attack_next = 0.7f;
|
||||
break;
|
||||
case AUTO_EMPTY:
|
||||
//Weapons_Sound(pl, CHAN_WEAPON, "weapon_mossberg.fire_empty");
|
||||
pl.w_attack_next = 0.2f;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pl.a_ammo3 > DBS_IDLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ammo check */
|
||||
#ifdef SERVER
|
||||
if (pl.shotgun_mag <= 0) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (pl.a_ammo1 <= 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SERVER
|
||||
TraceAttack_FireBullets(4, pl.origin + pl.view_ofs, 14, [0.17365,0.04362], WEAPON_DBS);
|
||||
sound(pl, CHAN_WEAPON, "weapons/sbarrel1.wav", 1, ATTN_NORM);
|
||||
pl.shotgun_mag--;
|
||||
Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_shells, __NULL__);
|
||||
#else
|
||||
View_SetMuzzleflash(MUZZLE_WEIRD);
|
||||
Weapons_ViewPunchAngle([-5,0,0]);
|
||||
pl.a_ammo1--;
|
||||
#endif
|
||||
Weapons_ViewAnimation(DBS_FIRE1);
|
||||
|
||||
pl.w_attack_next = 0.75;
|
||||
pl.w_idle_next = 2.5f;
|
||||
pl.w_idle_next = 1.5f;
|
||||
}
|
||||
|
||||
void
|
||||
w_dbs_reload(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
#ifdef CLIENT
|
||||
if (pl.a_ammo1 >= 8) {
|
||||
return;
|
||||
}
|
||||
if (pl.a_ammo2 <= 0) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (pl.shotgun_mag >= 8) {
|
||||
return;
|
||||
}
|
||||
if (pl.ammo_shells <= 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pl.a_ammo3 > DBS_IDLE) {
|
||||
return;
|
||||
}
|
||||
pl.a_ammo3 = DBS_RELOAD_START;
|
||||
pl.w_idle_next = 0.0f;
|
||||
w_baseshotgun_reload(player::mag_dbs, player::m_iAmmoShells, 16);
|
||||
}
|
||||
|
||||
void
|
||||
w_dbs_release(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
int s = w_baseshotgun_release(player::mag_dbs, player::m_iAmmoShells, 16);
|
||||
|
||||
if (pl.w_idle_next > 0.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pl.a_ammo3 == DBS_IDLE) {
|
||||
int r = floor(random(0,3));
|
||||
switch (r) {
|
||||
case 0:
|
||||
switch (s) {
|
||||
case SHOTGUN_IDLE:
|
||||
int r = (float)input_sequence % 3;
|
||||
if (r == 1) {
|
||||
Weapons_ViewAnimation(DBS_IDLE1);
|
||||
break;
|
||||
case 1:
|
||||
} else if (r == 2) {
|
||||
Weapons_ViewAnimation(DBS_IDLE2);
|
||||
break;
|
||||
case 2:
|
||||
} else {
|
||||
Weapons_ViewAnimation(DBS_IDLE3);
|
||||
break;
|
||||
}
|
||||
pl.w_idle_next = 15.0f;
|
||||
} else if (pl.a_ammo3 == DBS_RELOAD_START) {
|
||||
pl.w_idle_next = 5.0f;
|
||||
break;
|
||||
case SHOTGUN_BUSY:
|
||||
break;
|
||||
case SHOTGUN_START_RELOAD:
|
||||
Weapons_ViewAnimation(DBS_START_RELOAD);
|
||||
pl.a_ammo3 = DBS_RELOAD;
|
||||
pl.w_idle_next = 0.65f;
|
||||
} else if (pl.a_ammo3 == DBS_RELOAD) {
|
||||
break;
|
||||
case SHOTGUN_RELOAD:
|
||||
Weapons_ViewAnimation(DBS_ADDSHELL);
|
||||
#ifdef CLIENT
|
||||
pl.a_ammo1++;
|
||||
pl.a_ammo2--;
|
||||
|
||||
if (pl.a_ammo2 <= 0 || pl.a_ammo1 >= 8) {
|
||||
pl.a_ammo3 = DBS_RELOAD_END;
|
||||
}
|
||||
#else
|
||||
pl.shotgun_mag++;
|
||||
pl.ammo_shells--;
|
||||
Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_shells, pl.a_ammo3);
|
||||
sound(pl, CHAN_WEAPON, "weapons/reload3.wav", 1.0, ATTN_NORM);
|
||||
if (pl.ammo_shells <= 0 || pl.shotgun_mag >= 8) {
|
||||
pl.a_ammo3 = DBS_RELOAD_END;
|
||||
}
|
||||
#endif
|
||||
pl.w_idle_next = 0.5f;
|
||||
} else if (pl.a_ammo3 == DBS_RELOAD_END) {
|
||||
break;
|
||||
case SHOTGUN_END_RELOAD:
|
||||
Weapons_ViewAnimation(DBS_PUMP);
|
||||
#ifdef SERVER
|
||||
sound(pl, CHAN_WEAPON, "weapons/scock1.wav", 1.0, ATTN_NORM);
|
||||
#endif
|
||||
pl.a_ammo3 = DBS_IDLE;
|
||||
pl.w_idle_next = 10.0f;
|
||||
pl.w_attack_next = 0.5f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
w_dbs_crosshair(void)
|
||||
{
|
||||
|
|
|
@ -14,20 +14,31 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
NAILGUN_IDLE,
|
||||
NAILGUN_FIDGET1,
|
||||
NAILGUN_UNUSED1,
|
||||
NAILGUN_UNUSED2,
|
||||
NAILGUN_DEPLOY,
|
||||
NAILGUN_SHOOT1,
|
||||
NAILGUN_SHOOT2,
|
||||
NAILGUN_SHOOT3,
|
||||
};
|
||||
|
||||
void
|
||||
w_nailgun_precache(void)
|
||||
{
|
||||
precache_model("models/v_tfc_nailgun.mdl");
|
||||
precache_model("models/w_nailgun.mdl");
|
||||
precache_model("models/p_nailgun.mdl");
|
||||
precache_model("models/nail.mdl");
|
||||
}
|
||||
|
||||
void
|
||||
w_nailgun_updateammo(player pl)
|
||||
{
|
||||
#ifdef SERVER
|
||||
Weapons_UpdateAmmo(pl, __NULL__, __NULL__, __NULL__);
|
||||
#endif
|
||||
Weapons_UpdateAmmo(pl, __NULL__, pl.m_iAmmoNails, __NULL__);
|
||||
}
|
||||
|
||||
string
|
||||
|
@ -51,7 +62,7 @@ void
|
|||
w_nailgun_draw(void)
|
||||
{
|
||||
Weapons_SetModel("models/v_tfc_nailgun.mdl");
|
||||
Weapons_ViewAnimation(0);
|
||||
Weapons_ViewAnimation(NAILGUN_DEPLOY);
|
||||
}
|
||||
|
||||
float
|
||||
|
@ -60,6 +71,97 @@ w_nailgun_aimanim(void)
|
|||
return self.flags & FL_CROUCHING ? ANIM_CR_AIMCROWBAR : ANIM_AIMCROWBAR;
|
||||
}
|
||||
|
||||
void
|
||||
w_nailgun_shootnail(void)
|
||||
{
|
||||
static void w_rpg_shootrocket_touch(void) {
|
||||
remove(self);
|
||||
}
|
||||
|
||||
Weapons_MakeVectors();
|
||||
entity p = spawn();
|
||||
setmodel(p, "models/nail.mdl");
|
||||
setorigin(p, Weapons_GetCameraPos() + (v_forward * 8));
|
||||
p.owner = self;
|
||||
p.movetype = MOVETYPE_FLYMISSILE;
|
||||
p.solid = SOLID_BBOX;
|
||||
p.gravity = 0.5f;
|
||||
p.velocity = (v_forward * 1000);
|
||||
p.angles = vectoangles(p.velocity);
|
||||
p.touch = w_rpg_shootrocket_touch;
|
||||
p.think = Util_Destroy;
|
||||
p.nextthink = time + 5.0f;
|
||||
}
|
||||
|
||||
void
|
||||
w_nailgun_primary(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
int s = w_baseprojectile_fire(WEAPON_NAILGUN, player::m_iAmmoNails, w_nailgun_shootnail);
|
||||
|
||||
switch (s) {
|
||||
case AUTO_FIRE_FAILED:
|
||||
return;
|
||||
break;
|
||||
case AUTO_FIRED:
|
||||
case AUTO_LAST:
|
||||
int r = (float)input_sequence % 3;
|
||||
if (r == 1) {
|
||||
Weapons_ViewAnimation(NAILGUN_SHOOT1);
|
||||
} else if (r == 2) {
|
||||
Weapons_ViewAnimation(NAILGUN_SHOOT2);
|
||||
} else {
|
||||
Weapons_ViewAnimation(NAILGUN_SHOOT3);
|
||||
}
|
||||
Weapons_ViewAnimation(NAILGUN_SHOOT2);
|
||||
Weapons_ViewPunchAngle([-1,0,0]);
|
||||
pl.w_attack_next = 0.1f;
|
||||
break;
|
||||
case AUTO_EMPTY:
|
||||
pl.w_attack_next = 0.2f;
|
||||
break;
|
||||
}
|
||||
|
||||
pl.w_idle_next = 1.5f;
|
||||
}
|
||||
|
||||
void
|
||||
w_nailgun_hud(void)
|
||||
{
|
||||
#ifdef CLIENT
|
||||
player pl = (player)self;
|
||||
vector cross_pos;
|
||||
vector aicon_pos;
|
||||
|
||||
/* crosshair/laser */
|
||||
cross_pos = g_hudmins + (g_hudres / 2) + [-12,-12];
|
||||
drawsubpic(
|
||||
cross_pos,
|
||||
[24,24],
|
||||
g_cross_spr,
|
||||
[0.1875,0],
|
||||
[0.1875, 0.1875],
|
||||
[1,1,1],
|
||||
1.0f,
|
||||
DRAWFLAG_NORMAL
|
||||
);
|
||||
|
||||
HUD_DrawAmmo2();
|
||||
|
||||
aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
|
||||
drawsubpic(
|
||||
aicon_pos,
|
||||
[24,24],
|
||||
g_hud7_spr,
|
||||
[0,72/128],
|
||||
[24/256, 24/128],
|
||||
g_hud_color,
|
||||
pSeatLocal->m_flAmmo2Alpha,
|
||||
DRAWFLAG_ADDITIVE
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
w_nailgun_hudpic(int selected, vector pos, float a)
|
||||
{
|
||||
|
@ -98,11 +200,11 @@ weapon_t w_nailgun =
|
|||
.slot_pos = 0,
|
||||
.draw = w_nailgun_draw,
|
||||
.holster = __NULL__,
|
||||
.primary = __NULL__,
|
||||
.primary = w_nailgun_primary,
|
||||
.secondary = __NULL__,
|
||||
.reload = __NULL__,
|
||||
.release = __NULL__,
|
||||
.crosshair = __NULL__,
|
||||
.crosshair = w_nailgun_hud,
|
||||
.precache = w_nailgun_precache,
|
||||
.pickup = __NULL__,
|
||||
.updateammo = w_nailgun_updateammo,
|
||||
|
|
|
@ -14,20 +14,47 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#define TFC_RPG_ROCKET_SPEED 900.0f
|
||||
|
||||
enum
|
||||
{
|
||||
RPG_IDLE1,
|
||||
RPG_FIDGET1,
|
||||
RPG_FIRE,
|
||||
RPG_HOLSTER1,
|
||||
RPG_DRAW1,
|
||||
RPG_HOLSTER2,
|
||||
RPG_DRAW2,
|
||||
RPG_RELOAD_START,
|
||||
RPG_RELOAD,
|
||||
RPG_RELOAD_END,
|
||||
RPG_IDLE2,
|
||||
RPG_FIDGET2
|
||||
};
|
||||
|
||||
void
|
||||
w_rpg_precache(void)
|
||||
{
|
||||
precache_model("models/v_tfc_rpg.mdl");
|
||||
precache_model("models/w_rpg.mdl");
|
||||
precache_model("models/p_rpg.mdl");
|
||||
precache_model("models/rpgrocket.mdl");
|
||||
}
|
||||
|
||||
int
|
||||
w_rpg_pickup(int new, int startammo)
|
||||
{
|
||||
#ifdef SERVER
|
||||
player pl = (player)self;
|
||||
pl.mag_rpg = bound(0, pl.mag_rpg + 4, 4);
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
w_rpg_updateammo(player pl)
|
||||
{
|
||||
#ifdef SERVER
|
||||
Weapons_UpdateAmmo(pl, __NULL__, __NULL__, __NULL__);
|
||||
#endif
|
||||
Weapons_UpdateAmmo(pl, pl.mag_rpg, pl.m_iAmmoRockets, __NULL__);
|
||||
}
|
||||
|
||||
string
|
||||
|
@ -35,6 +62,7 @@ w_rpg_wmodel(void)
|
|||
{
|
||||
return "models/w_rpg.mdl";
|
||||
}
|
||||
|
||||
string
|
||||
w_rpg_pmodel(void)
|
||||
{
|
||||
|
@ -54,12 +82,143 @@ w_rpg_draw(void)
|
|||
Weapons_ViewAnimation(0);
|
||||
}
|
||||
|
||||
void
|
||||
w_rpg_shootrocket(void)
|
||||
{
|
||||
static void w_rpg_shootrocket_touch(void) {
|
||||
FX_Explosion(self.origin);
|
||||
remove(self);
|
||||
}
|
||||
|
||||
Weapons_MakeVectors();
|
||||
entity p = spawn();
|
||||
setmodel(p, "models/rpgrocket.mdl");
|
||||
setorigin(p, Weapons_GetCameraPos() + (v_forward * 8));
|
||||
p.owner = self;
|
||||
p.movetype = MOVETYPE_FLYMISSILE;
|
||||
p.solid = SOLID_BBOX;
|
||||
p.gravity = 0.5f;
|
||||
p.velocity = (v_forward * TFC_RPG_ROCKET_SPEED);
|
||||
p.angles = vectoangles(p.velocity);
|
||||
p.touch = w_rpg_shootrocket_touch;
|
||||
p.think = Util_Destroy;
|
||||
p.nextthink = time + 5.0f;
|
||||
}
|
||||
|
||||
void
|
||||
w_rpg_primary(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
int s = w_baseprojectile_fire(WEAPON_RPG, player::mag_rpg, w_rpg_shootrocket);
|
||||
|
||||
switch (s) {
|
||||
case AUTO_FIRE_FAILED:
|
||||
return;
|
||||
break;
|
||||
case AUTO_FIRED:
|
||||
Weapons_ViewAnimation(RPG_FIRE);
|
||||
Weapons_ViewPunchAngle([-2,0,0]);
|
||||
pl.w_attack_next = 0.8f;
|
||||
break;
|
||||
case AUTO_LAST:
|
||||
Weapons_ViewAnimation(RPG_FIRE);
|
||||
Weapons_ViewPunchAngle([-2,0,0]);
|
||||
pl.w_attack_next = 0.8f;
|
||||
break;
|
||||
case AUTO_EMPTY:
|
||||
pl.w_attack_next = 0.2f;
|
||||
break;
|
||||
}
|
||||
|
||||
pl.w_idle_next = 1.5f;
|
||||
}
|
||||
|
||||
void
|
||||
w_rpg_reload(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
w_baseshotgun_reload(player::mag_rpg, player::m_iAmmoRockets, 4);
|
||||
}
|
||||
|
||||
void
|
||||
w_rpg_release(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
int s = w_baseshotgun_release(player::mag_rpg, player::m_iAmmoRockets, 4);
|
||||
|
||||
switch (s) {
|
||||
case SHOTGUN_IDLE:
|
||||
int r = (float)input_sequence % 3;
|
||||
if (r == 1) {
|
||||
Weapons_ViewAnimation(RPG_IDLE1);
|
||||
} else if (r == 2) {
|
||||
Weapons_ViewAnimation(RPG_FIDGET1);
|
||||
} else {
|
||||
Weapons_ViewAnimation(RPG_FIDGET2);
|
||||
}
|
||||
pl.w_idle_next = 5.0f;
|
||||
break;
|
||||
case SHOTGUN_BUSY:
|
||||
break;
|
||||
case SHOTGUN_START_RELOAD:
|
||||
Weapons_ViewAnimation(RPG_RELOAD_START);
|
||||
break;
|
||||
case SHOTGUN_RELOAD:
|
||||
Weapons_ViewAnimation(RPG_RELOAD);
|
||||
break;
|
||||
case SHOTGUN_END_RELOAD:
|
||||
Weapons_ViewAnimation(RPG_RELOAD_END);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float
|
||||
w_rpg_aimanim(void)
|
||||
{
|
||||
return self.flags & FL_CROUCHING ? ANIM_CR_AIMCROWBAR : ANIM_AIMCROWBAR;
|
||||
}
|
||||
|
||||
void
|
||||
w_rpg_hud(void)
|
||||
{
|
||||
#ifdef CLIENT
|
||||
player pl = (player)self;
|
||||
vector cross_pos;
|
||||
vector aicon_pos;
|
||||
|
||||
/* crosshair/laser */
|
||||
cross_pos = g_hudmins + (g_hudres / 2) + [-12,-12];
|
||||
drawsubpic(
|
||||
cross_pos,
|
||||
[24,24],
|
||||
g_cross_spr,
|
||||
[0,0],
|
||||
[0.1875, 0.1875],
|
||||
[1,1,1],
|
||||
1,
|
||||
DRAWFLAG_NORMAL
|
||||
);
|
||||
|
||||
/* ammo counters */
|
||||
HUD_DrawAmmo1();
|
||||
HUD_DrawAmmo2();
|
||||
|
||||
/* ammo icon */
|
||||
aicon_pos = g_hudmins + [g_hudres[0] - 48, g_hudres[1] - 42];
|
||||
drawsubpic(
|
||||
aicon_pos,
|
||||
[24,24],
|
||||
"sprites/640hud7.spr_0.tga",
|
||||
[120/256,72/128],
|
||||
[24/256, 24/128],
|
||||
g_hud_color,
|
||||
pSeatLocal->m_flAmmo2Alpha,
|
||||
DRAWFLAG_ADDITIVE
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
w_rpg_hudpic(int selected, vector pos, float a)
|
||||
{
|
||||
|
@ -80,13 +239,13 @@ weapon_t w_rpg =
|
|||
.slot_pos = 0,
|
||||
.draw = w_rpg_draw,
|
||||
.holster = __NULL__,
|
||||
.primary = __NULL__,
|
||||
.primary = w_rpg_primary,
|
||||
.secondary = __NULL__,
|
||||
.reload = __NULL__,
|
||||
.release = __NULL__,
|
||||
.crosshair = __NULL__,
|
||||
.reload = w_rpg_reload,
|
||||
.release = w_rpg_release,
|
||||
.crosshair = w_rpg_hud,
|
||||
.precache = w_rpg_precache,
|
||||
.pickup = __NULL__,
|
||||
.pickup = w_rpg_pickup,
|
||||
.updateammo = w_rpg_updateammo,
|
||||
.wmodel = w_rpg_wmodel,
|
||||
.pmodel = w_rpg_pmodel,
|
||||
|
|
|
@ -28,14 +28,6 @@ enum
|
|||
SBS_IDLE3
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SBS_IDLE,
|
||||
SBS_RELOAD_START,
|
||||
SBS_RELOAD,
|
||||
SBS_RELOAD_END
|
||||
};
|
||||
|
||||
void
|
||||
w_sbs_precache(void)
|
||||
{
|
||||
|
@ -52,9 +44,7 @@ w_sbs_precache(void)
|
|||
void
|
||||
w_sbs_updateammo(player pl)
|
||||
{
|
||||
#ifdef SERVER
|
||||
Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_shells, __NULL__);
|
||||
#endif
|
||||
Weapons_UpdateAmmo(pl, pl.mag_sbs, pl.m_iAmmoShells, __NULL__);
|
||||
}
|
||||
string w_sbs_wmodel(void)
|
||||
{
|
||||
|
@ -74,7 +64,7 @@ w_sbs_pickup(int new, int startammo)
|
|||
{
|
||||
#ifdef SERVER
|
||||
player pl = (player)self;
|
||||
pl.shotgun_mag = bound(0, pl.shotgun_mag + 8, 8);
|
||||
pl.mag_sbs = bound(0, pl.mag_sbs + 8, 8);
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
@ -84,10 +74,6 @@ w_sbs_draw(void)
|
|||
{
|
||||
Weapons_SetModel("models/v_tfc_12gauge.mdl");
|
||||
Weapons_ViewAnimation(SBS_DRAW);
|
||||
#ifdef SERVER
|
||||
player pl = (player)self;
|
||||
Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_shells, __NULL__);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -100,124 +86,72 @@ void
|
|||
w_sbs_primary(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
if (pl.w_attack_next) {
|
||||
int s = w_baseshotgun_fire(WEAPON_SBS, player::mag_sbs, 6, 4, [0.04, 0.04, 0]);
|
||||
|
||||
switch (s) {
|
||||
case AUTO_FIRE_FAILED:
|
||||
return;
|
||||
break;
|
||||
case AUTO_FIRED:
|
||||
Weapons_ViewAnimation(SBS_FIRE1);
|
||||
Weapons_ViewPunchAngle([-2,0,0]);
|
||||
//Weapons_Sound(pl, CHAN_WEAPON, "weapon_mossberg.fire");
|
||||
pl.w_attack_next = 0.5f;
|
||||
break;
|
||||
case AUTO_LAST:
|
||||
Weapons_ViewAnimation(SBS_FIRE1);
|
||||
Weapons_ViewPunchAngle([-2,0,0]);
|
||||
//Weapons_Sound(pl, CHAN_WEAPON, "weapon_mossberg.fire");
|
||||
pl.w_attack_next = 0.5f;
|
||||
break;
|
||||
case AUTO_EMPTY:
|
||||
//Weapons_Sound(pl, CHAN_WEAPON, "weapon_mossberg.fire_empty");
|
||||
pl.w_attack_next = 0.2f;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pl.a_ammo3 > SBS_IDLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ammo check */
|
||||
#ifdef SERVER
|
||||
if (pl.shotgun_mag <= 0) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (pl.a_ammo1 <= 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SERVER
|
||||
TraceAttack_FireBullets(4, pl.origin + pl.view_ofs, 6, [0.17365,0.04362], WEAPON_SBS);
|
||||
Sound_Play(pl, CHAN_WEAPON, "weapon_sbs.fire");
|
||||
pl.shotgun_mag--;
|
||||
Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_shells, __NULL__);
|
||||
#else
|
||||
View_SetMuzzleflash(MUZZLE_WEIRD);
|
||||
Weapons_ViewPunchAngle([-5,0,0]);
|
||||
pl.a_ammo1--;
|
||||
#endif
|
||||
Weapons_ViewAnimation(SBS_FIRE1);
|
||||
|
||||
pl.w_attack_next = 0.75;
|
||||
pl.w_idle_next = 2.5f;
|
||||
pl.w_idle_next = 1.5f;
|
||||
}
|
||||
|
||||
void
|
||||
w_sbs_reload(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
#ifdef CLIENT
|
||||
if (pl.a_ammo1 >= 8) {
|
||||
return;
|
||||
}
|
||||
if (pl.a_ammo2 <= 0) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (pl.shotgun_mag >= 8) {
|
||||
return;
|
||||
}
|
||||
if (pl.ammo_shells <= 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pl.a_ammo3 > SBS_IDLE) {
|
||||
return;
|
||||
}
|
||||
pl.a_ammo3 = SBS_RELOAD_START;
|
||||
pl.w_idle_next = 0.0f;
|
||||
w_baseshotgun_reload(player::mag_sbs, player::m_iAmmoShells, 8);
|
||||
}
|
||||
|
||||
void
|
||||
w_sbs_release(void)
|
||||
{
|
||||
player pl = (player)self;
|
||||
int s = w_baseshotgun_release(player::mag_sbs, player::m_iAmmoShells, 8);
|
||||
|
||||
if (pl.w_idle_next > 0.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pl.a_ammo3 == SBS_IDLE) {
|
||||
int r = floor(random(0,3));
|
||||
switch (r) {
|
||||
case 0:
|
||||
switch (s) {
|
||||
case SHOTGUN_IDLE:
|
||||
int r = (float)input_sequence % 3;
|
||||
if (r == 1) {
|
||||
Weapons_ViewAnimation(SBS_IDLE1);
|
||||
break;
|
||||
case 1:
|
||||
} else if (r == 2) {
|
||||
Weapons_ViewAnimation(SBS_IDLE2);
|
||||
break;
|
||||
case 2:
|
||||
} else {
|
||||
Weapons_ViewAnimation(SBS_IDLE3);
|
||||
break;
|
||||
}
|
||||
pl.w_idle_next = 15.0f;
|
||||
} else if (pl.a_ammo3 == SBS_RELOAD_START) {
|
||||
pl.w_idle_next = 5.0f;
|
||||
break;
|
||||
case SHOTGUN_BUSY:
|
||||
break;
|
||||
case SHOTGUN_START_RELOAD:
|
||||
Weapons_ViewAnimation(SBS_START_RELOAD);
|
||||
pl.a_ammo3 = SBS_RELOAD;
|
||||
pl.w_idle_next = 0.65f;
|
||||
} else if (pl.a_ammo3 == SBS_RELOAD) {
|
||||
break;
|
||||
case SHOTGUN_RELOAD:
|
||||
Weapons_ViewAnimation(SBS_ADDSHELL);
|
||||
#ifdef CLIENT
|
||||
pl.a_ammo1++;
|
||||
pl.a_ammo2--;
|
||||
|
||||
if (pl.a_ammo2 <= 0 || pl.a_ammo1 >= 8) {
|
||||
pl.a_ammo3 = SBS_RELOAD_END;
|
||||
}
|
||||
#else
|
||||
pl.shotgun_mag++;
|
||||
pl.ammo_shells--;
|
||||
Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_shells, pl.a_ammo3);
|
||||
Sound_Play(pl, CHAN_WEAPON, "weapon_sbs.reload");
|
||||
if (pl.ammo_shells <= 0 || pl.shotgun_mag >= 8) {
|
||||
pl.a_ammo3 = SBS_RELOAD_END;
|
||||
}
|
||||
#endif
|
||||
pl.w_idle_next = 0.5f;
|
||||
} else if (pl.a_ammo3 == SBS_RELOAD_END) {
|
||||
break;
|
||||
case SHOTGUN_END_RELOAD:
|
||||
Weapons_ViewAnimation(SBS_PUMP);
|
||||
#ifdef SERVER
|
||||
Sound_Play(pl, CHAN_WEAPON, "weapon_sbs.cock");
|
||||
#endif
|
||||
pl.a_ammo3 = SBS_IDLE;
|
||||
pl.w_idle_next = 10.0f;
|
||||
pl.w_attack_next = 0.5f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
w_sbs_crosshair(void)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue