Merge branch 'main' of https://github.com/nzp-team/quakec into menu-qc

This commit is contained in:
MotoLegacy 2024-11-25 21:18:09 -08:00
commit 5bf23dce3a
11 changed files with 166 additions and 47 deletions

View file

@ -2093,7 +2093,7 @@ vector(entity e, float s, vector p) getsurfaceclippedpoint = #439; /* Part of DP
float(string s) tokenize = #441; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND*/
string(float n) argv = #442; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND*/
void(entity e, entity tagentity, string tagname) setattachment = #443; /* Part of DP_GFX_QUAKE3MODELTAGS*/
searchhandle(string pattern, enumflags:float{SB_CASEINSENSITIVE=1<<0,SB_FULLPACKAGEPATH=1<<1,SB_ALLOWDUPES=1<<2,SB_FORCESEARCH=1<<3} flags, float quiet, optional string filterpackage) search_begin = #444; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE
searchhandle(string pattern, enumflags:float{SB_CASEINSENSITIVE=1<<0,SB_FULLPACKAGEPATH=1<<1,SB_ALLOWDUPES=1<<2,SB_FORCESEARCH=1<<3,SB_MULTISEARCH=1<<4} flags, float quiet, optional string filterpackage) search_begin = #444; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE
initiate a filesystem scan based upon filenames. Be sure to call search_end on the returned handle. SB_FULLPACKAGEPATH interprets the filterpackage arg as a full package path to avoid gamedir ambiguity, equivelent to whichpack's WP_FULLPACKAGEPATH flag. SB_ALLOWDUPES allows returning multiple entries with the same name (but different package, useful with search_fopen). SB_FORCESEARCH requires use of the filterpackage and SB_FULLPACKAGEPATH flag, initiating searches from gamedirs/packages which are not currently active. */
void(searchhandle handle) search_end = #445; /* Part of DP_QC_FS_SEARCH, DP_QC_FS_SEARCH_PACKFILE*/

View file

@ -779,6 +779,7 @@ void(float width, float height) HUD_Rounds =
else if (rounds_change == 7)//blink white while fading back
{
stopwatch_round_isactive = true;
stopwatch_round_hr = stopwatch_round_min = stopwatch_round_sec = 0;
if (!color_shift_init)
{
color_shift_end[0] = 107;

View file

@ -25,6 +25,8 @@
*/
float need_vid_reload;
void() ToggleMenu =
{
if (serverkey("constate") != "disconnected")
@ -65,6 +67,95 @@ float(float isnew) SetZombieSkinning =
return PREDRAW_NEXT;
};
//
// GenerateAlphaTransparencyQ3Shaders()
// What a mouth-full! Anyway, NZ:P supports
// alpha transparency via a pseudo-hack where
// if the last character of a model is "$"
// we render with special blend modes. To
// do the same on FTE, we need to generate
// Quake III "shader" files. Returns TRUE
// if we had shader modifications.
//
float() GenerateAlphaTransparencyQ3Shaders =
{
searchhandle alias_models;
float amod_count;
float need_reload = false;
alias_models = search_begin("*.mdl:*/*.mdl:*/*/*.mdl:*/*/*/*.mdl:*/*/*/*/*.mdl:*/*/*/*/*/*.mdl", SB_CASEINSENSITIVE | SB_MULTISEARCH, true); // gross.
amod_count = search_getsize(alias_models);
for (float i = 0; i < amod_count; i++) {
string full_path = search_getfilename(alias_models, i);
// Single out character before ".mdl" extension.
string special_character = substring(full_path, strlen(full_path) - 5, 1);
// Early out, not a special guy.
if (special_character != "$")
continue;
// Isolate its basename.. manually :(
string basename = "";
for (float j = strlen(full_path); j > 0; j--) {
if (str2chr(full_path, j) == str2chr("/", 0)) {
// Strip path
basename = substring(full_path, j + 1, strlen(full_path) - (j + 1));
// Strip extension
basename = substring(basename, 0, strlen(basename) - 4);
break;
}
}
if (basename == "") {
print(sprintf("[ERROR]: Unable to calculate basename for [%s]!\n", full_path));
continue;
}
float shader_file;
string shader_path = sprintf("scripts/%s.shader", basename);
// Check if the shader already exists.
shader_file = fopen(shader_path, FILE_READ);
if (shader_file != -1) {
fclose(shader_file);
continue;
}
// Begin to write.
shader_file = fopen(shader_path, FILE_WRITE);
if (shader_file == -1) {
print(sprintf("[ERROR]: Unable to generate Q3 shader for [%s]!\n", full_path));
continue;
}
// Body of our shader file we're writing.
string shader_content = sprintf(
"//\n"
"// Quake III Shader generated automatically by Nazi Zombies: Portable. Do not modify.\n"
"//\n"
"\n"
"%s_0.lmp\n" // full_path
"{\n"
" program defaultskin\n"
" progblendfunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA\n"
" diffusemap %s_0.tga\n" // full_path
" alphafunc ge128\n"
"}\n"
, full_path, full_path);
fputs(shader_file, shader_content);
fclose(shader_file);
need_reload = true;
}
search_end(alias_models);
return need_reload;
};
noref void(float apiver, string enginename, float enginever) CSQC_Init =
{
setwindowcaption("Nazi Zombies: Portable");
@ -150,10 +241,19 @@ noref void(float apiver, string enginename, float enginever) CSQC_Init =
}
InitKerningMap();
// If we've made shader changes, we should perform
// a vid_reload at a reasonable time.
need_vid_reload = GenerateAlphaTransparencyQ3Shaders();
};
noref void() CSQC_WorldLoaded =
{
if (need_vid_reload == true) {
need_vid_reload = false;
localcmd("vid_reload\n");
}
Achievement_Init();
Particles_Init();
nameprint_time = time + 8;

View file

@ -218,9 +218,9 @@ float Link (entity from, entity to) {
float i;
entity tempe;
for (i = 0; i < MAX_WAY_TARGETS; i++) {
tempe = find (world, waynum, from.targets[i]);
tempe = find(world, waynum, from.targets[i]);
if (tempe == world || tempe == to) {
if (tempe == world || !from.targets[i]) {
from.targets[i] = to.waynum;
bprint(PRINT_HIGH, "Linked waypoint ");
bprint(PRINT_HIGH, to.waynum);
@ -253,24 +253,38 @@ void () Link_Waypoints =
return;
if (Waypoint_Linked_To(current_way, active_way)) {
bprint(PRINT_HIGH, "These waypoints are already linked!\n");
bprint(PRINT_HIGH, "[INFO]: These waypoints are already linked!\n");
return;
}
float i;
entity tempe;
for (i = 0; i < MAX_WAY_TARGETS; i++) {
tempe = findfloat (world, waynum, active_way.targets[i]);
if (tempe == world) {
if (Link(active_way, current_way)) {
// First pass - if the target field is blank no extra
// validation is needed, just link.
if (!active_way.targets[i]) {
if (Link(active_way, current_way))
return;
}
bprint(PRINT_HIGH, "[INFO]: Got Linkable Waypoints but Linking failed!\n");
return;
}
// Second pass - if the targets field is occupied
// check if the waypoint still exists, link if it
// does not.
if (find(world, waynum, active_way.targets[i]) == world) {
bprint(PRINT_HIGH, sprintf("[INFO]: Found Waypoint ID %s but not entity, overwriting link..\n", active_way.targets[i]));
if (Link(active_way, current_way))
return;
bprint(PRINT_HIGH, " ..Failed!\n");
return;
}
}
bprint(PRINT_HIGH, "no targets remaining!\n");
bprint(PRINT_HIGH, "[INFO]: All Waypoint links occupied for this Waypoint!\n");
}

View file

@ -225,7 +225,7 @@ var struct guninventory_struct
//Knife
.float knife_delay;
.float bowie;
.float has_bowie_knife;
//Grenades
.float grenades;

View file

@ -643,7 +643,8 @@ void() Perk_RandomDecide =
}
// Choose which of the eight machines we want to become, if permitted.
while (true) {
float num_attempts;
for(num_attempts = 64; num_attempts > 0; num_attempts--) {
i = random();
// Quick Revive
if (i < (1/8) && (self.spawnflags & SPAWNFLAG_PERKRANDOM_QUICKREVIVE)) {
@ -694,6 +695,9 @@ void() Perk_RandomDecide =
break;
}
}
if (!num_attempts)
objerror("perk_random: Failed 64 times to pick a Perk-A-Cola. Bailing!\n");
};
void() Perk_RandomPrecaches =

View file

@ -202,10 +202,7 @@ void () WallWeapon_TouchTrigger =
Player_RemoveScore(other, wcost);
if (self.enemy) {
oldent = self;
self = self.enemy;
self.use();
self = oldent;
SUB_UseTargets();
}
}
} else
@ -247,10 +244,7 @@ void () WallWeapon_TouchTrigger =
Player_RemoveScore(other, wcost);
if (self.enemy) {
oldent = self;
self = self.enemy;
self.use();
self = oldent;
SUB_UseTargets();
}
}
}
@ -282,10 +276,7 @@ void () WallWeapon_TouchTrigger =
nzp_bettyprompt(other);
if (self.enemy)
{
oldent = self;
self = self.enemy;
self.use();
self = oldent;
SUB_UseTargets();
}
}
other.semi_actions |= SEMIACTION_USE;
@ -315,10 +306,7 @@ void () WallWeapon_TouchTrigger =
other.primary_grenades = 4;
if (self.enemy)
{
oldent = self;
self = self.enemy;
self.use();
self = oldent;
SUB_UseTargets();
}
}
other.semi_actions |= SEMIACTION_USE;
@ -326,7 +314,7 @@ void () WallWeapon_TouchTrigger =
}
else if (self.weapon == W_BOWIE)
{
if (!other.bowie) {
if (!other.has_bowie_knife) {
useprint(other, 4, self.cost2, self.weapon);
if (other.button7)
{
@ -341,16 +329,13 @@ void () WallWeapon_TouchTrigger =
other.ach_tracker_coll++;
if (self.enemy)
{
oldent = self;
self = self.enemy;
self.use();
self = oldent;
SUB_UseTargets();
}
entity tempz;
tempz = self;
self = other;
Set_W_Frame(15, 30, 2.75, 0, 0, W_PlayTakeOut, "models/weapons/knife/v_bowie.mdl", false, S_BOTH, true);
self.bowie = 1;
self.has_bowie_knife = true;
}
}
}
@ -378,10 +363,7 @@ void () WallWeapon_TouchTrigger =
other.reload_delay = 0;
Player_RemoveScore(other, self.cost);
if (self.enemy) {
oldent = self;
self = self.enemy;
self.use();
self = oldent;
SUB_UseTargets();
}
tempe = self;
self = other;

View file

@ -395,6 +395,23 @@ void() worldspawn =
G_WORLDTEXT = 1;
G_PERKS = 0;
G_PERKPOWER = 0;
//
// World Gravity Multiplier
//
// FIXME: This should technically poll sv_gravity but
// we do not currently enforce a default that resets
// on a new server.
float sv_gravity = 800;
// worldspawn "gravity" field is a multiplier to be applied
// to sv_gravity.
if (!world.gravity) world.gravity = 1;
world.gravity = clamp(world.gravity, 0.1, 2);
// Update the cvar for the server.
cvar_set("sv_gravity", ftos(sv_gravity * world.gravity));
}
void() SpectatorConnect =

View file

@ -926,7 +926,8 @@ void() PlayerSpawn =
setsize(self, PLAYER_MINS_STANDING, PLAYER_MAXS_STANDING);
}
self.stance = 2;
self.has_bowie_knife = false;
self.stance = PLAYER_STANCE_STAND;
self.new_ofs_z = self.view_ofs_z;
self.oldz = self.origin_z;
self.grenades = self.grenades | 1; // add frag grenades to player inventory

View file

@ -1268,17 +1268,17 @@ void() WeaponCore_Melee =
// Apply damage to the entity.
if (trace_ent.takedamage) {
float melee_damage = WepDef_CalculateMeleeDamage(self.weapon, self.bowie);
float melee_damage = WepDef_CalculateMeleeDamage(self.weapon, self.has_bowie_knife);
DamageHandler (trace_ent, self, melee_damage, DMG_TYPE_MELEE);
}
}
}
// Grab animation stats for our melee weapon.
float start_frame = WepDef_GetMeleeFirstFrame(self.weapon, did_lunge, self.bowie);
float end_frame = WepDef_GetMeleeLastFrame(self.weapon, did_lunge, self.bowie);
float anim_duration = WepDef_GetMeleeAnimDuration(self.weapon, did_lunge, self.bowie);
string model_path = WepDef_GetMeleeModel(self.weapon, self.bowie);
float start_frame = WepDef_GetMeleeFirstFrame(self.weapon, did_lunge, self.has_bowie_knife);
float end_frame = WepDef_GetMeleeLastFrame(self.weapon, did_lunge, self.has_bowie_knife);
float anim_duration = WepDef_GetMeleeAnimDuration(self.weapon, did_lunge, self.has_bowie_knife);
string model_path = WepDef_GetMeleeModel(self.weapon, self.has_bowie_knife);
// Ensure we play the Take Out animation if the melee model is not our active weapon
void() end_func;

View file

@ -1550,7 +1550,7 @@ vector GetWeaponADSOfs(float wep) =
{
case W_COLT:
case W_BIATCH:
return [-5479.2, 1850, -4000];
return [-3479.2, 1050, -4000];
case W_KAR:
case W_ARMAGEDDON:
return [-5495.9, 3006.9, -6000];
@ -1928,7 +1928,7 @@ float(float wep, float frametype, optional float z) GetFrame =
case SPRINT_OUT_END:
return 31;
case TAKE_OUT_START:
return 38;
return 37;
case TAKE_OUT_END:
return 41;
case PUT_OUT_START: