Merge pull request #69 from nzp-team/map-compatibility

Add support for loading select maps from NZ:P Beta
This commit is contained in:
cypress 2024-01-07 18:06:39 -05:00 committed by GitHub
commit 51b4ce3819
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 1167 additions and 563 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
build/*
source/server/hash_table.qc
bin/fteqcc.log

View file

@ -21,6 +21,8 @@ There are no prerequisites or dependancies needed to build QuakeC other than a w
Before you can build the NZ:P QuakeC, you must either [download](https://github.com/nzp-team/quakec/archive/refs/heads/main.zip) this repository (easy) or [clone it](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) (for developers).
[Python](https://www.python.org/) 3.7 or above is required to execute additional required components for hash table generation. You can install the [required modules](https://raw.githubusercontent.com/nzp-team/QCHashTableGenerator/main/requirements.txt) with `pip -r requirements.txt` pointing to the provided file.
To build, simply navigate to the `tools` directory and run the `qc-compiler-*` script for your platform. If unfamiliar with executing shell (`.sh`) scripts on Linux systems, give this [itsFOSS article](https://itsfoss.com/run-shell-script-linux/) a read.
After having done this, a `build` directory will have been created, and inside of it will be more directories named after every platform. Copy the contents of the platform directories into your `nzp` game directory. (Example: For PSP, copy `progs.dat` and `progs.lno` from `standard/handheld` to `PSP/GAME/nzportable/nzp`).

176
bin/qc_hash_generator.py Normal file
View file

@ -0,0 +1,176 @@
"""
Nazi Zombies: Portable QuakeC CRC generator
Takes input .CSV files and outputs an FTEQCC-compilable
QuakeC struct with its contents, always assumes the first
entry should be IBM 3740 CRC16 hashed, adding its length
as an entry as well, for collision detection.
"""
import argparse
import pandas
import sys
import os
from fastcrc import crc16
from colorama import Fore, Style
from dataclasses import dataclass
args = {}
struct_fields = []
original_lengths = []
original_names = []
COL_BLUE = Fore.BLUE
COL_RED = Fore.RED
COL_YEL = Fore.YELLOW
COL_GREEN = Fore.GREEN
COL_NONE = Style.RESET_ALL
ITYPE_FLOAT = 0
ITYPE_STRING = 1
ITYPE_CRC = 2
@dataclass
class StructField:
'''
Class for fields that are added to the QuakeC struct.
'''
name: str
item_type: int = ITYPE_FLOAT
def write_qc_file(csv_data):
'''
Writes the data obtained into an FTEQCC-compilable
struct.
'''
with open(args['output_file'], 'w') as output:
# Define the struct.
output.write('var struct {\n')
# Write out all of it's types..
for fields in struct_fields:
if fields.item_type == ITYPE_STRING:
output.write('string ')
else:
output.write('float ')
output.write(f'{fields.name};\n')
# Close the struct.
output.write('}')
# Now, the name of it
struct_name = args['struct_name']
output.write(f'{struct_name}[]=')
output.write('{\n')
# We can begin writing the actual data..
value_counter = 0
for value in csv_data.values:
output.write('{')
entry_counter = 0
for entry in value:
if struct_fields[entry_counter].item_type != ITYPE_STRING:
output.write(f'{str(entry)},')
else:
output.write(f'\"{entry}\",')
entry_counter += 1
# Write the length of the first entry
output.write(str(original_lengths[value_counter]))
# Close entry, add comma if not the last..
output.write('}')
if value_counter + 1 < len(csv_data.values):
output.write(',')
# Leave comment referring to the unhashed-value
output.write(f' // {original_names[value_counter]}')
output.write('\n')
value_counter += 1
# End struct!
output.write('};\n')
def create_qc_structfields(csv_data):
'''
Parses the .CSV data to create new StructField
entries given the .CSV specific requirements.
'''
global struct_fields
column_count = 0
for column in csv_data.columns:
# Assume first entry is what we always want
# to hash, append _crc to it, too.
if column_count == 0:
item_type = ITYPE_CRC
item_name = column + '_crc'
else:
item_type = ITYPE_STRING
item_name = column
struct_fields.append(StructField(item_name, item_type))
column_count += 1
# Always append a field that will store the
# length of the unhashed-CRC.
struct_fields.append(StructField('crc_strlen', ITYPE_FLOAT))
def generate_qc_file(csv_data):
'''
Calls for population of StructFields and prompts
for writing the .QC file output.
'''
create_qc_structfields(csv_data)
write_qc_file(csv_data)
def read_csv_data():
'''
Parses the input_file .CSV into a Pandas dictionary,
performs the hashing on the first indexes, and sorts
in ascending order.
'''
global original_lengths, original_names
csv_data = pandas.read_csv(args['input_file'])
# Grab every value and turn the first entry into a hash.
for value in csv_data.values:
original_lengths.append(len(value[0]))
original_names.append(value[0])
value[0] = int(crc16.ibm_3740(str.encode(value[0])))
# Now order everything by ascending order
csv_data = csv_data.sort_values(csv_data.columns[0])
original_lengths = [original_lengths[i] for i in csv_data.index]
original_names = [original_names[i] for i in csv_data.index]
return csv_data
def fetch_cli_arguments():
'''
Initiates ArgParser with all potential command line arguments.
'''
global args
parser = argparse.ArgumentParser(description='IBM 3740 CRC16 hash generator in FTE QuakeC-readable data structure.')
parser.add_argument('-i', '--input-file',
help='.CSV input file to parse.', required=True)
parser.add_argument('-o', '--output-file',
help='File name for generated .QC file.', default='hashes.qc')
parser.add_argument('-n', '--struct-name',
help='Name of the struct generated.', default='asset_conversion_table')
args = vars(parser.parse_args())
def main():
fetch_cli_arguments()
if not os.path.isfile(args['input_file']):
print(f'{COL_RED}Error{COL_NONE}: Input .CSV file does not exist. Exiting.')
sys.exit()
csv_data = read_csv_data()
generate_qc_file(csv_data)
if __name__ == '__main__':
main()

View file

@ -5,6 +5,7 @@
../source/shared/weapon_defines.qc
../source/server/defs/custom.qc
../source/server/clientfuncs.qc
../source/server/hash_table.qc
../source/server/dummies.qc
../source/server/rounds.qc
@ -50,3 +51,5 @@
../source/server/ai/zombie_core.qc
../source/server/ai/crawler_core.qc
../source/server/ai/dog_core.qc
../source/server/utilities/map_compatibility.qc

View file

@ -7,6 +7,7 @@
../source/shared/weapon_defines.qc
../source/server/defs/custom.qc
../source/server/clientfuncs.qc
../source/server/hash_table.qc
../source/server/non_fte_specifics.qc
@ -54,3 +55,5 @@
../source/server/ai/zombie_core.qc
../source/server/ai/crawler_core.qc
../source/server/ai/dog_core.qc
../source/server/utilities/map_compatibility.qc

View file

@ -569,11 +569,15 @@ noref void(float isnew) CSQC_Ent_Update =
self.solid = SOLID_SLIDEBOX;
setmodelindex(self, self.modelindex);
if (self.stance == 2)
setsize(self, PLAYER_MINS_STANDING, PLAYER_MAXS_STANDING);
else
setsize(self, PLAYER_MINS_CROUCHING, PLAYER_MAXS_CROUCHING);
if (map_compatibility_mode != MAP_COMPAT_BETA) {
if (self.stance == 2)
setsize(self, PLAYER_MINS_STANDING, PLAYER_MAXS_STANDING);
else
setsize(self, PLAYER_MINS_CROUCHING, PLAYER_MAXS_CROUCHING);
} else {
setsize(self, PLAYER_MINS_QUAKE, PLAYER_MAXS_QUAKE);
}
} else {
if(isnew)
addentity(self);
@ -1461,20 +1465,9 @@ noref void() CSQC_Parse_Event =
revive_icons[reviveoff_id].draw = false;
active_revive_icons--;
break;
// case EVENT_POINTUPDATE:
// float playernum = readbyte();
// float temppoints = readlong();
// RegisterPointChange(readlong(), playernum);
// float tempkills = readlong();
// string tempname = readstring();
// switch(playernum) {
// case 1: playerpoints[0] = temppoints; playerkills[0] = tempkills; playernames[0] = tempname; break;
// case 2: playerpoints[1] = temppoints; playerkills[1] = tempkills; playernames[1] = tempname; break;
// case 3: playerpoints[2] = temppoints; playerkills[2] = tempkills; playernames[2] = tempname; break;
// case 4: playerpoints[3] = temppoints; playerkills[3] = tempkills; playernames[3] = tempname; break;
// }
// break;
case EVENT_MAPTYPE:
map_compatibility_mode = readbyte();
break;
case EVENT_BLACKOUT:
fade_time = readbyte();
fade_type = readbyte();

View file

@ -530,7 +530,14 @@ void() Load_Waypoints
if (file == -1)
{
dprint("Error: file not found \n");
#ifdef FTE
dprint("LoadWaypointData: No .way file found, trying Beta format..\n");
Compat_TryLoadBetaWaypoints();
#endif // FTE
return;
}

View file

@ -325,6 +325,7 @@ void CalcDistances() {
void creator_way_touch();
void() Compat_TryLoadBetaWaypoints;
void LoadWaypointData() {
float file, point;
string h;
@ -336,7 +337,14 @@ void LoadWaypointData() {
if (file == -1)
{
dprint("Error: file not found \n");
#ifdef FTE
dprint("LoadWaypointData: No .way file found, trying Beta format..\n");
Compat_TryLoadBetaWaypoints();
#endif // FTE
return;
}

View file

@ -206,6 +206,13 @@ void(float what) play_sound_z =
}
};
void(__inout vector what, float howmuch) vector_scale_hack =
{
what_x *= howmuch;
what_y *= howmuch;
what_z *= howmuch;
}
void(float which) SetZombieHitBox =
{
@ -213,152 +220,95 @@ void(float which) SetZombieHitBox =
if(self.currentHitBoxSetup == which)
return;
//which = IDLE_BBOX;
switch(which)
{
case EMPTY_BBOX:
{
/*setorigin(self.head,'0 0 0');
setsize (self.head, '0 0 0', '0 0 0');
setorigin(self.larm, '0 0 0');
setsize (self.larm, '0 0 0','0 0 0');
setorigin(self.rarm, '0 0 0');
setsize (self.rarm, '0 0 0','0 0 0');*/
self.head.view_ofs = '0 0 0';
self.rarm.view_ofs = '0 0 0';
self.larm.view_ofs = '0 0 0';
self.currentHitBoxSetup = EMPTY_BBOX;
return;
}
break;
case IDLE_BBOX:
{
//setsize (self.head, '-5 -5 -5', '5 5 5');
self.head.bbmins = '-5 -5 -5';
self.head.bbmaxs = '5 5 5';
self.head.view_ofs = '0 10 35';
//setsize (self.larm, '-5 -5 -15', '5 5 15');
self.larm.bbmins = '-5 -5 -15';
self.larm.bbmaxs = '5 5 15';
self.larm.view_ofs = '-10 10 10';
//setsize (self.rarm, '-5 -5 -15', '5 5 15');
self.rarm.bbmins = '-5 -5 -15';
self.rarm.bbmaxs = '5 5 15';
self.rarm.view_ofs = '10 10 10';
self.currentHitBoxSetup = IDLE_BBOX;
return;
}
break;
case WALK1_BBOX:
{
//setsize (self.head, '-5 -5 -5', '5 5 5');
self.head.bbmins = '-5 -5 -5';
self.head.bbmaxs = '5 5 5';
self.head.view_ofs = '2 -3 35';
//setsize (self.head, '-3 -8 30', '7 2 40');
//self.head.view_ofs = '0 0 0';
//setsize (self.larm, '-5 -7 -15', '5 7 15');
self.larm.bbmins = '-5 -7 -15';
self.larm.bbmaxs = '5 7 15';
self.larm.view_ofs = '-10 -4 15';
//setsize (self.rarm, '-5 -8 -11', '5 8 11');
self.rarm.bbmins = '-5 -8 -11';
self.rarm.bbmaxs = '5 8 11';
self.rarm.view_ofs = '10 11 11';
self.currentHitBoxSetup = WALK1_BBOX;
return;
}
break;
case WALK2_BBOX:
{
//setsize (self.head, '-7 -5 -5', '7 5 5');
self.head.bbmins = '-7 -5 -5';
self.head.bbmaxs = '7 5 5';
self.head.view_ofs = '-11 6 36';
//setsize (self.larm, '-5 -6 -15', '5 6 15');
self.larm.bbmins = '-5 -6 -15';
self.larm.bbmaxs = '5 6 15';
self.larm.view_ofs = '-14 3 15';
//setsize (self.rarm, '-5 -5 -11', '5 5 11');
self.rarm.bbmins = '-5 -5 -11';
self.rarm.bbmaxs = '5 5 11';
self.rarm.view_ofs = '4 13 11';
self.currentHitBoxSetup = WALK2_BBOX;
return;
}
break;
case WALK3_BBOX:
{
//setsize (self.head, '-5 -5 -5', '5 5 5');
self.head.bbmins = '-5 -5 -5';
self.head.bbmaxs = '5 5 5';
self.head.view_ofs = '-2 13 31';
//setsize (self.larm, '-4 -6 -14', '4 6 14');
self.larm.bbmins = '-4 -6 -14';
self.larm.bbmaxs = '4 6 14';
self.larm.view_ofs = '-12 3 11';
//setsize (self.rarm, '-5 -5 -11', '5 5 11');
self.rarm.bbmins = '-5 -5 -11';
self.rarm.bbmaxs = '5 5 11';
self.rarm.view_ofs = '14 6 12';
self.currentHitBoxSetup = WALK3_BBOX;
return;
}
break;
case JOG_BBOX:
{
//setsize (self.head, '-5 -5 -5', '5 5 5');
self.head.bbmins = '-5 -5 -5';
self.head.bbmaxs = '5 5 5';
self.head.view_ofs = '0 5 36';
//setsize (self.larm, '-5 -13 -5', '5 13 5');
self.larm.bbmins = '-5 -13 -5';
self.larm.bbmaxs = '5 13 5';
self.larm.view_ofs = '-8 19 24';
//setsize (self.rarm, '-5 -13 -5', '5 13 5');
self.rarm.bbmins = '-5 -13 -5';
self.rarm.bbmaxs = '5 13 5';
self.rarm.view_ofs = '10 19 24';
self.currentHitBoxSetup = JOG_BBOX;
return;
}
break;
case RUN_BBOX:
{
//setsize (self.head, '-5 -5 -5', '5 5 5');
self.head.bbmins = '-5 -5 -5';
self.head.bbmaxs = '5 5 5';
self.head.view_ofs = '3 17 32';
//setsize (self.larm, '-4 -10 -9', '4 10 9');
self.larm.bbmins = '-4 -10 -9';
self.larm.bbmaxs = '4 10 9';
self.larm.view_ofs = '-12 28 18';
//setsize (self.rarm, '-4 -13 -10', '4 13 10');
self.rarm.bbmins = '-4 -13 -10';
self.rarm.bbmaxs = '4 13 10';
self.rarm.view_ofs = '12 -2 19';
self.currentHitBoxSetup = RUN_BBOX;
return;
}
break;
case CRAWLER_BBOX:
{
self.head.bbmins = '-5 -5 -5';
self.head.bbmaxs = '5 5 5';
self.head.view_ofs = '2 18 -14';
@ -370,30 +320,36 @@ void(float which) SetZombieHitBox =
self.rarm.bbmins = '-4 -13 -10';
self.rarm.bbmaxs = '4 13 10';
self.rarm.view_ofs = '12 15 -25';
self.currentHitBoxSetup = CRAWLER_BBOX;
return;
}
break;
default: //also known as BASE_BBOX
{
//setsize (self.head, '-5 -5 -5', '5 5 5');
self.head.bbmins = '-5 -5 -5';
self.head.bbmaxs = '5 5 5';
self.head.view_ofs = '0 0 35';
//setsize (self.larm, '-5 -5 -15', '5 5 15');
self.larm.bbmins = '-5 -5 -15';
self.larm.bbmaxs = '5 5 15';
self.larm.view_ofs = '-10 0 5';
//setsize (self.rarm, '-5 -5 -15', '5 5 15');
self.rarm.bbmins = '-5 -5 -15';
self.rarm.bbmaxs = '5 5 15';
self.rarm.view_ofs = '10 0 5';
self.currentHitBoxSetup = BASE_BBOX;
return;
}
break;
}
self.currentHitBoxSetup = which;
if (map_compatibility_mode == MAP_COMPAT_BETA) {
vector_scale_hack(self.head.bbmins, self.head.scale);
vector_scale_hack(self.head.bbmaxs, self.head.scale);
vector_scale_hack(self.head.view_ofs, self.head.scale);
vector_scale_hack(self.larm.bbmins, self.larm.scale);
vector_scale_hack(self.larm.bbmaxs, self.larm.scale);
vector_scale_hack(self.larm.view_ofs, self.larm.scale);
vector_scale_hack(self.rarm.bbmins, self.rarm.scale);
vector_scale_hack(self.rarm.bbmaxs, self.rarm.scale);
vector_scale_hack(self.rarm.view_ofs, self.rarm.scale);
}
};
@ -1762,10 +1718,24 @@ void(entity where) spawn_a_zombieB =
szombie.gravity = 1.0;
szombie.mins = '-8 -8 -32';//-16 16 -32
szombie.maxs = '8 8 30';//16 16 40
if (map_compatibility_mode == MAP_COMPAT_BETA) {
szombie.mins = '-6 -6 -24';
szombie.maxs = '6 6 22';
#ifdef FTE
// Need to force-set the hull for FTE or else Zombie setorigin()
// calls will fail in tight spaces.
szombie.hull = 1;
#endif // FTE
} else {
szombie.mins = '-8 -8 -32';
szombie.maxs = '8 8 30';
}
setsize (szombie, szombie.mins, szombie.maxs);//-16,-16,-32,16,16,40
setsize (szombie, szombie.mins, szombie.maxs);
//====================================
@ -1860,6 +1830,9 @@ void(entity where) spawn_a_zombieB =
szombie.head.skin = szombie.larm.skin = szombie.rarm.skin = szombie.skin;
if (map_compatibility_mode == MAP_COMPAT_BETA)
szombie.head.scale = szombie.larm.scale = szombie.rarm.scale = szombie.scale = 0.73;
// set up timer for next spawn
zombie_spawn_timer = zombie_spawn_delay + time;
};

View file

@ -24,7 +24,6 @@
Boston, MA 02111-1307, USA
*/
string(string asset) convert_old_asset_path;
void() NotifyGameEnd =
{
@ -67,6 +66,14 @@ void SetUpdate(entity client, float type, float val1, float val2, float val3)
}
#ifdef FTE
void(float mode, entity to) ReportMapMode = {
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EVENT_MAPTYPE);
WriteByte(MSG_MULTICAST, mode);
msg_entity = to;
multicast('0 0 0', MULTICAST_ONE);
}
void(entity to, float type, float cost, float weapon) useprint = {
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, EVENT_USEPRINT);
@ -668,7 +675,7 @@ void(entity ent) Ent_FakeRemove =
void(string modelname) Precache_Set = // Precache model, and set myself to it
{
modelname = convert_old_asset_path(modelname);
modelname = Compat_ConvertOldAssetPath(modelname);
precache_model(modelname);
setmodel(self, modelname);
};

View file

@ -194,10 +194,7 @@ void() GetDown =
push_away_zombies();
// Force the player to prone.
if (self.stance == 2) self.new_ofs_z = self.view_ofs_z - (PLAYER_CROUCH_HEIGHT + PLAYER_PRONE_HEIGHT);
if (self.stance == 1) self.new_ofs_z = self.view_ofs_z - PLAYER_CROUCH_HEIGHT;
self.stance = 0;
setsize(self, PLAYER_MINS_CROUCHING, PLAYER_MAXS_CROUCHING);
Player_SetStance(self, PLAYER_STANCE_PRONE, false);
// Get rid of Mule Kick Weapon
for(float i = 0; i < MAX_PLAYER_WEAPONS; i++) {
@ -335,7 +332,7 @@ void() GetDown =
// Spawn Revive Sprite in Co-Op
if (player_count) {
EnableReviveIcon(revive_index, self.origin + VEC_VIEW_OFS);
EnableReviveIcon(revive_index, self.origin + VIEW_OFS_HL);
self.electro_targeted = revive_index;
revive_index++;
}
@ -349,18 +346,11 @@ void () GetUp =
// Play Getting Up Animation
PAnim_GetUp();
// Player is able to get up from here
if (Player_CanStandHere(self)) {
self.new_ofs_z = self.view_ofs_z + PLAYER_CROUCH_HEIGHT + PLAYER_PRONE_HEIGHT;
self.stance = 2;
setsize(self, PLAYER_MINS_STANDING, PLAYER_MAXS_STANDING);
}
// They can't, so make them crouch instead
else {
self.new_ofs_z = self.view_ofs_z + PLAYER_PRONE_HEIGHT;
self.stance = 1;
PAnim_CrouchWalk7(); // bad hack so they dont just end up fucking standing in a wall.
}
Player_SetStance(self, PLAYER_STANCE_STAND, false);
// Bad hack: if we're crouching, just play some dummy crouchwalk frames.
if (self.stance == PLAYER_STANCE_CROUCH)
PAnim_CrouchWalk7();
self.health = 100;
self.downedloop = 0; // used for death timing vs endgame

View file

@ -244,6 +244,8 @@ void Set_W_Frame (float startframe, float endframe, float duration, float funcca
.void() animend;
.void(optional float t) animend2;
string(string path) Compat_ConvertOldAssetPath;
//Null functions
void() SUB_Null = {};
void() SUB_Null2 = {};
@ -253,7 +255,8 @@ void() SUB_Null2 = {};
#define VEC_HULL2_MIN '-32 -32 -24'
#define VEC_HULL2_MAX '32 32 64'
#define VEC_VIEW_OFS '0 0 32'
#define VIEW_OFS_HL '0 0 32'
#define VIEW_OFS_QK '0 0 22'
.string name;
vector trace_plane_normal;

View file

@ -266,6 +266,7 @@ string(float num)
// 2001-11-15 DarkPlaces general builtin functions by Lord Havoc end
// DP_QC_STRING_CASE_FUNCTIONS
string (string s) strtolower = #480;
float (float caseinsensitive, string s) crc16 = #494;
void (string trackname) songegg = #500;
void () nzp_maxammo = #501;
void (entity who) grenade_pulse = #502;

View file

@ -58,12 +58,6 @@ void() info_end = {remove(self);};
//// beta removal
void() monster_dog = {remove(self);};
void() item_pap = {remove(self);};
//void() item_juggernog = {remove(self);};
//void() item_flopper = {remove(self);};
//void() item_douple = {remove(self);};
//void() item_speed = {remove(self);};
//void() item_revive = {remove(self);};
void() palm_tree_closed = {remove(self);};
void() func_model = {remove(self);};
void() wooden_crate = {remove(self);};

View file

@ -1435,34 +1435,4 @@ void() perk_random =
}
}
}
}
void() item_revive =
{
perk_revive();
self.origin_z += 8;
}
void() item_juggernog =
{
perk_juggernog();
self.origin_z += 8;
}
void() item_speed =
{
perk_speed();
self.origin_z += 8;
}
void() item_douple =
{
perk_double();
self.origin_z += 8;
}
void() item_flopper =
{
perk_flopper();
self.origin_z += 8;
}
}

View file

@ -315,7 +315,7 @@ void() misc_model =
// Make static (not animate) if not given a frame range, and not affected by gravity
// also remains active if it has a targetname (so it can be killtargeted/toggled)
if (!self.last_frame && !(self.spawnflags & 1) && !(self.spawnflags & MISC_MODEL_SOLID) && !self.targetname)
if (!self.last_frame && !(self.spawnflags & 1) && !(self.spawnflags & MISC_MODEL_SOLID) && !self.targetname && self.classname != "place_model")
makestatic(self);
// if it as a custom animation range
@ -334,7 +334,8 @@ void() misc_model =
else
self.state = STATE_INVISIBLE;
misc_model_use();
if (self.classname != "place_model")
misc_model_use();
};
//
@ -343,8 +344,10 @@ void() misc_model =
//
void() place_model =
{
self.classname = "place_model";
// Grab an updated model path.
self.model = convert_old_asset_path(self.model);
self.model = Compat_ConvertOldAssetPath(self.model);
// Convert the VEC_HULL bounds to match mdlsz.
self.mdlsz = '64 64 88';

View file

@ -101,6 +101,7 @@ void(entity ent) MBOX_FreeEnt =
ent.classname = "freeMboxEntity";
ent.touch = SUB_Null;
ent.think = SUB_Null;
ent.scale = 1;
ent.effects = 0;
ent.frame = 0;
@ -237,6 +238,10 @@ void() findboxspot =
setmodel (newspot, mystery_box_model);
newspot.frame = 0;
setsize (newspot, VEC_HULL2_MIN, VEC_HULL2_MAX);
// Scale down for NZ:P Beta
if (map_compatibility_mode == MAP_COMPAT_BETA)
newspot.scale = 0.75;
}
//
@ -276,6 +281,10 @@ void() MBOX_FindNewSpot =
setmodel(new_box, mystery_box_model);
setsize(new_box, VEC_HULL2_MIN, VEC_HULL2_MAX);
// Scale down for NZ:P Beta
if (map_compatibility_mode == MAP_COMPAT_BETA)
new_box.scale = 0.75;
// Spawn the Box Glow if permitted
if (!(new_box.spawnflags & MBOX_SPAWNFLAG_NOLIGHT))
{
@ -590,7 +599,14 @@ void() Create_Floating_Weapon =
gun.movetype = MOVETYPE_NOCLIP;
gun.solid = SOLID_NOT;
makevectors(self.angles);
gun.velocity = v_up*15;
// Float up less in NZ:P Beta, and scale down.
if (map_compatibility_mode == MAP_COMPAT_BETA) {
gun.velocity = v_up*10;
gun.scale = 0.75;
} else {
gun.velocity = v_up*15;
}
gun.owner = self;
self.boxweapon = gun;

View file

@ -407,9 +407,9 @@ void() perk_pap =
self.oldmodel = "sounds/machines/packapunch/upgrade.wav";
}
self.model = convert_old_asset_path(self.model);
self.weapon2model = convert_old_asset_path(self.weapon2model);
self.door_model_name = convert_old_asset_path(self.door_model_name);
self.model = Compat_ConvertOldAssetPath(self.model);
self.weapon2model = Compat_ConvertOldAssetPath(self.weapon2model);
self.door_model_name = Compat_ConvertOldAssetPath(self.door_model_name);
// Precaches
// FIXME: Don't hardcode weapon precaches here.

View file

@ -62,6 +62,7 @@ inline void(entity ent) PU_FreeEnt =
ent.touch = SUB_Null;
ent.think = SUB_Null;
ent.frame = 0;
ent.scale = 1;
ent.effects = 0;
};
@ -754,6 +755,11 @@ void(vector where, float type) Spawn_Powerup =
setmodel(sparkle,"models/sprites/sprkle.spr");
// Scale down for NZ:P Beta
if (map_compatibility_mode == MAP_COMPAT_BETA) {
powerup.scale = sparkle.scale = 0.66;
}
sparkle.think = PU_SparkleThink;
sparkle.nextthink = time + 0.1;

View file

@ -269,7 +269,11 @@ void(entity which) Spawns_SetUpPoint =
{
which.solid = SOLID_BBOX;
setsize(which, [-8, -8, -32], [8, 8, 40]);
Spawns_DropToFloor(which);
// NZ:P Beta was pretty relaxed when it came to spawn validity..
// so doing this causes breakage on maps like Ankunft.
if (map_compatibility_mode != MAP_COMPAT_BETA)
Spawns_DropToFloor(which);
if (!which.weapon) {
which.weapon = SPAWN_START_WEAPON;

View file

@ -93,7 +93,7 @@ void() SUB_UseTargets =
//
// kill the killtagets
//
if (self.killtarget)
if (self.killtarget && self.killtarget != self.target)
{
t = world;
do

View file

@ -238,32 +238,6 @@ void() trigger_activator =
self.touch = trigger_activator_touch;
}
#define SPAWNFLAG_TRIGGERCMD_NOPLAYER 1
#define SPAWNFLAG_TRIGGERCMD_NOSPEC 2
void() trigger_stuffcmd_touch =
{
// First, lets make sure this is a client
if (other.classname != "player" && other.classname != "spectator")
return;
// Don't interact with players
if ((self.spawnflags & SPAWNFLAG_TRIGGERCMD_NOPLAYER) && other.classname == "player")
return;
// Don't interact with spectators
if ((self.spawnflags & SPAWNFLAG_TRIGGERCMD_NOSPEC) && other.classname == "spectator")
return;
// Run the command.
stuffcmd(other, strcat(self.message, "\n"));
}
void() trigger_stuffcmd =
{
InitTrigger();
self.touch = trigger_stuffcmd_touch;
}
void() trigger_interact_touch =
{
if (other.classname != "player" || other.downed || other.isBuying == true || !PlayerIsLooking(other, self))

View file

@ -138,7 +138,7 @@ void () WallWeapon_TouchTrigger =
float wcost;
if (other.classname != "player" || other.downed || other.isBuying || !PlayerIsLooking(other, self)) {
if (other.classname != "player" || other.downed || other.isBuying || (map_compatibility_mode != MAP_COMPAT_BETA && !PlayerIsLooking(other, self))) {
return;
}

View file

@ -427,6 +427,4 @@ void() item_barricade =
setsize(self, '-20 -20 -64', '20 20 16');
setorigin(self, self.origin);
spawn_boxes();
};
void() item_cover = {item_barricade();};
};

View file

@ -28,6 +28,7 @@
void() LS_Setup;
void() PU_Init;
void() Compat_Init;
void() SUB_Remove = {remove(self);}
//called when starting server/loading the map
@ -133,6 +134,7 @@ void() StartFrame =
updateDogRound();
InitRounds();
Compat_Init();
}
}
}
@ -527,244 +529,4 @@ void() EndFrame =
if (cheats_have_been_activated == false && cvar("sv_cheats") == 1) {
cheats_have_been_activated = true;
}
};
//
// convert_old_asset_path(asset)
// a large switch statement to convert asset paths made for
// older versions of nzp to the new standard
//
string(string asset) convert_old_asset_path =
{
string lowered_asset = strzone(strtolower(asset));
string ret = "";
switch(lowered_asset) {
case "progs/player.mdl":
ret = "models/player.mdl";
break;
case "progs/ai/zal(.mdl":
ret = "models/ai/zal(.mdl";
break;
case "models/machines/quick_revive.mdl":
ret = "models/machines/quake_scale/quick_revive.mdl";
break;
case "models/machines/juggernog.mdl":
ret = "models/machines/quake_scale/juggernog.mdl";
break;
case "models/machines/speed_cola.mdl":
ret = "models/machines/quake_scale/speed_cola.mdl";
break;
case "progs/misc/double_tap.mdl":
case "models/machines/double_tap.mdl":
ret = "models/machines/quake_scale/double_tap.mdl";
break;
case "progs/misc/flopper.mdl":
case "models/machines/flopper.mdl":
ret = "models/machines/quake_scale/flopper.mdl";
break;
case "models/machines/staminup.mdl":
ret = "models/machines/quake_scale/staminup.mdl";
break;
case "models/machines/deadshot.mdl":
ret = "models/machines/quake_scale/deadshot.mdl";
break;
case "models/machines/mulekick.mdl":
ret = "models/machines/quake_scale/mulekick.mdl";
break;
case "progs/misc/pap.mdl":
case "models/machines/pap.mdl":
ret = "models/machines/quake_scale/pap.mdl";
break;
case "progs/sprites/lamp_glow.spr":
ret = "models/sprites/lamp_glow.spr";
break;
case "progs/sprites/lamp_glow2.spr":
// HACK HACK -- old maps that used this sprite were working with
// a broken offset, fix it.
self.origin_z -= 32;
ret = "models/sprites/lamp_glow2.spr";
break;
case "progs/sprites/lamp_glow3.spr":
ret = "models/sprites/lamp_glow.spr";
break;
case "progs/props/kino_boxes2.mdl":
ret = "models/props/Kino_boxes2.mdl";
break;
case "progs/props/kino_boxes3.mdl":
ret = "models/props/Kino_boxes3.mdl";
break;
case "progs/props/kino_boxes4.mdl":
ret = "models/props/Kino_boxes4.mdl";
break;
case "progs/props/teddy.mdl":
case "progs/misc/teddy.mdl":
ret = "models/props/teddy.mdl";
break;
case "progs/props/kino_box.mdl":
ret = "models/props/Kino_box.mdl";
break;
case "progs/props/table_dinner.mdl":
ret = "models/props/table_dinner.mdl";
break;
case "progs/props/table_sq.mdl":
ret = "models/props/table_sq.mdl";
break;
case "progs/props/rebar.mdl":
ret = "models/props/rebar.mdl";
break;
case "progs/props/kino_table.mdl":
ret = "models/props/Kino_table.mdl";
break;
case "progs/props/kino_couch.mdl":
ret = "models/props/kino_couch.mdl";
break;
case "progs/props/metal_chair.mdl":
ret = "models/props/metal_chair.mdl";
break;
case "progs/props/sandbags.mdl":
ret = "models/props/sandbags.mdl";
break;
case "progs/props/dentist_chair.mdl":
ret = "models/props/dentist_chair.mdl";
break;
case "progs/props/bath.mdl":
ret = "models/props/bath.mdl";
break;
case "progs/props/shelf.mdl":
ret = "models/props/shelf.mdl";
break;
case "progs/props/dummy.mdl":
ret = "models/props/dummy.mdl";
break;
case "progs/props/stand.mdl":
ret = "models/props/stand.mdl";
break;
case "progs/props/radio.mdl":
ret = "models/props/radio.mdl";
break;
case "progs/props/radiator.mdl":
ret = "models/props/radiator.mdl";
break;
case "progs/props/lamp_ndu.mdl":
ret = "models/props/lamp_ndu.mdl";
break;
case "progs/props/lamp_ndu45.mdl":
ret = "models/props/lamp_ndu45.mdl";
break;
case "progs/props/barrel_m.mdl":
ret = "models/props/barrel_m.mdl";
break;
case "progs/props/lamp_oil.mdl":
ret = "models/props/lamp_oil.mdl";
break;
case "progs/props/piano.mdl":
ret = "models/props/piano.mdl";
break;
case "progs/props/pisuar.mdl":
ret = "models/props/pisuar.mdl";
break;
case "progs/props/teleporter.mdl":
ret = "models/props/teleporter.mdl";
break;
case "progs/props/chandelier.mdl":
ret = "models/props/chandelier.mdl";
break;
case "progs/props/vanity_table.mdl":
ret = "models/props/vanity_table.mdl";
break;
case "progs/props/trash_con.mdl":
ret = "models/props/trash_con.mdl";
break;
case "progs/props/fridge.mdl":
ret = "models/props/fridge.mdl";
break;
case "progs/props/kino_chairset.mdl":
ret = "models/props/kino_chairset.mdl";
break;
case "progs/props/kino_lounge.mdl":
ret = "models/props/Kino_lounge.mdl";
break;
case "progs/props/kino_stageprop.mdl":
ret = "models/props/kino_stageprop.mdl";
break;
case "progs/props/mainframe_pad.mdl":
ret = "models/props/mainframe_pad.mdl";
break;
case "progs/props/tree_ch.mdl":
ret = "models/props/tree_ch.mdl";
break;
case "progs/props/treesl.mdl":
ret = "models/props/treesl.mdl";
break;
case "progs/props/bed.mdl":
ret = "models/props/bed.mdl";
break;
case "progs/gmodels/g_mp40.mdl":
ret = "models/weapons/mp40/g_mp40.mdl";
break;
case "progs/gmodels/g_thomp.mdl":
ret = "models/weapons/thomp/g_thomp.mdl";
break;
case "progs/gmodels/g_betty.mdl":
ret = "models/weapons/grenade/g_betty.mdl";
break;
case "progs/gmodels/g_fg.mdl":
ret = "models/weapons/fg42/g_fg.mdl";
break;
case "progs/gmodels/g_m1.mdl":
ret = "models/weapons/garand/g_m1.mdl";
break;
case "progs/gmodels/g_sawnoff.mdl":
ret = "models/weapons/sawnoff/g_sawnoff.mdl";
break;
case "progs/gmodels/g_trench.mdl":
ret = "models/weapons/trench/g_trench.mdl";
break;
case "progs/gmodels/g_bar.mdl":
ret = "models/weapons/bar/g_bar.mdl";
break;
case "progs/gmodels/g_grenade.mdl":
ret = "models/weapons/grenade/g_grenade.mdl";
break;
case "progs/gmodels/g_gewehr.mdl":
ret = "models/weapons/gewehr/g_gewehr.mdl";
break;
case "progs/gmodels/g_bowie.mdl":
ret = "models/weapons/knife/g_bowie.mdl";
break;
case "progs/gmodels/g_type.mdl":
ret = "models/weapons/type/g_type.mdl";
break;
case "progs/gmodels/g_ppsh.mdl":
ret = "models/weapons/ppsh/g_ppsh.mdl";
break;
case "progs/gmodels/g_stg.mdl":
ret = "models/weapons/stg/g_stg.mdl";
break;
case "models/misc/lightning.spr":
ret = "models/sprites/lightning.spr";
break;
case "models/derped/wall_lamp.mdl":
ret = "models/props/lamp_wall.mdl";
break;
case "models/machines/power_switch.mdl":
ret = "models/machines/quake_scale/power_switch.mdl";
break;
case "models/machines/hl_scale/packapunch/p_machine.mdl":
ret = "models/machines/hl_scale/pap/p_machine.mdl";
break;
case "models/machines/hl_scale/packapunch/p_roller.mdl":
ret = "models/machines/hl_scale/pap/p_roller.mdl";
break;
case "models/machines/hl_scale/packapunch/p_flag.mdl":
ret = "models/machines/hl_scale/pap/p_flag.mdl";
break;
default:
ret = asset;
break;
}
strunzone(lowered_asset);
return ret;
};
};

View file

@ -32,13 +32,15 @@ void() Spawns_Init;
void() SUB_UseTargets;
void() rec_downed;
#define PLAYER_START_HEALTH 100
#define PLAYER_START_HEALTH 100
#define PLAYER_CROUCH_HEIGHT 25
#define PLAYER_PRONE_HEIGHT 23
#define PLAYER_CROUCH_DIFFERENCE_HL 25
#define PLAYER_PRONE_DIFFERENCE_HL 23
#define PLAYER_CROUCH_DIFFERENCE_QK 15
#define PLAYER_PRONE_DIFFERENCE_QK 13
#define PLAYER_ANIM_WALK 1
#define PLAYER_ANIM_SPRINT 2
#define PLAYER_ANIM_WALK 1
#define PLAYER_ANIM_SPRINT 2
//
// Player 3rd Person Animations
@ -267,11 +269,95 @@ float(float dir) checkMovement =
//
float(entity who) Player_CanStandHere =
{
tracebox(who.origin, PLAYER_MINS_STANDING, PLAYER_MAXS_STANDING, who.origin, true, who);
// There shouldn't be any real reason we'd care about this since beta maps don't support
// stance changing impacting the bbox, but still, consistency..
if (map_compatibility_mode == MAP_COMPAT_BETA)
tracebox(who.origin, PLAYER_MINS_QUAKE, PLAYER_MAXS_QUAKE, who.origin, true, who);
else
tracebox(who.origin, PLAYER_MINS_STANDING, PLAYER_MAXS_STANDING, who.origin, true, who);
return !trace_startsolid;
}
//
// Player_SetStance(who, preferred_stance, play_animation)
// Lowers the camera height as needed, registers
// preferred stance, plays animation, and sets
// bounding box (if applicable).
//
void(entity who, float preferred_stance, float play_animation) Player_SetStance =
{
// Don't bother if we're already the desired stance, or if it wasn't valid
if (who.stance == preferred_stance || preferred_stance < 0 || preferred_stance > 2)
return;
// First check -- if we want to stand, only crouch if there
// is no space for it.
if (preferred_stance == PLAYER_STANCE_STAND && !Player_CanStandHere(who))
preferred_stance = PLAYER_STANCE_CROUCH;
// Set the bounding box
if (map_compatibility_mode != MAP_COMPAT_BETA) {
if (preferred_stance != PLAYER_STANCE_STAND)
setsize(self, PLAYER_MINS_CROUCHING, PLAYER_MAXS_CROUCHING);
else
setsize(self, PLAYER_MINS_STANDING, PLAYER_MAXS_STANDING);
}
// NZ:P Beta should change the stances by a different amount,
// to avoid looking like you're in the ground..
float height_diff_crouch, height_diff_prone;
if (map_compatibility_mode == MAP_COMPAT_BETA) {
height_diff_crouch = PLAYER_CROUCH_DIFFERENCE_QK;
height_diff_prone = PLAYER_PRONE_DIFFERENCE_QK;
} else {
height_diff_crouch = PLAYER_CROUCH_DIFFERENCE_HL;
height_diff_prone = PLAYER_PRONE_DIFFERENCE_HL;
}
// Prone while standing? Lower to crouch + prone height.
if (who.stance == PLAYER_STANCE_STAND && preferred_stance == PLAYER_STANCE_PRONE)
who.new_ofs_z = who.view_ofs_z - (height_diff_crouch + height_diff_prone);
// Prone while crouching? Lower to prone height.
else if (who.stance == PLAYER_STANCE_CROUCH && preferred_stance == PLAYER_STANCE_PRONE)
who.new_ofs_z = who.view_ofs_z - height_diff_prone;
// Crouch while proning? Raise to crouch height/take away prone difference.
else if (who.stance == PLAYER_STANCE_PRONE && preferred_stance == PLAYER_STANCE_CROUCH)
who.new_ofs_z = who.view_ofs_z + height_diff_prone;
// Crouch while standing? Lower to crouch height.
else if (who.stance == PLAYER_STANCE_STAND && preferred_stance == PLAYER_STANCE_CROUCH)
who.new_ofs_z = who.view_ofs_z - height_diff_crouch;
// Stand while crouching? Raise to stand height/take away crouch difference.
else if (who.stance == PLAYER_STANCE_CROUCH && preferred_stance == PLAYER_STANCE_STAND)
who.new_ofs_z = who.view_ofs_z + height_diff_crouch;
// Stand while proning? Raise to stand height/take away crouch + prone difference.
else if (who.stance == PLAYER_STANCE_PRONE && preferred_stance == PLAYER_STANCE_STAND)
who.new_ofs_z = who.view_ofs_z + (height_diff_crouch + height_diff_prone);
// Set the stance value
who.stance = preferred_stance;
// Animation playback
if (play_animation == true) {
entity tempe = self;
self = who;
switch(who.stance) {
case PLAYER_STANCE_STAND: PAnim_Stand(); break;
case PLAYER_STANCE_CROUCH: PAnim_Crouch(); break;
case PLAYER_STANCE_PRONE: PAnim_Prone(); break;
default: break;
}
self = tempe;
}
}
void() PlayerJump =
{
if (!(self.flags & FL_ONGROUND)
@ -304,25 +390,14 @@ void(float override) JumpCheck =
if (self.downed)
return;
if (self.stance == 2) {
if (self.stance == PLAYER_STANCE_STAND) {
// naievil -- stop sprinting if we jump, which is a real mechanic from the game that we never implemented
if (self.sprinting) {
W_SprintStop();
}
PlayerJump();
} else if (self.view_ofs_z == self.new_ofs_z && (self.flags & FL_ONGROUND) && Player_CanStandHere(self)) {
switch(self.stance) {
case 0:
self.new_ofs_z = self.view_ofs_z + PLAYER_CROUCH_HEIGHT + PLAYER_PRONE_HEIGHT;
self.stance = 2;
break;
case 1:
self.new_ofs_z = self.view_ofs_z + PLAYER_CROUCH_HEIGHT;
self.stance = 2;
break;
default: break;
}
setsize(self, PLAYER_MINS_STANDING, PLAYER_MAXS_STANDING);
} else if (self.view_ofs_z == self.new_ofs_z && (self.flags & FL_ONGROUND)) {
Player_SetStance(self, PLAYER_STANCE_STAND, true);
}
} else
self.flags = self.flags | FL_JUMPRELEASED;
@ -334,7 +409,13 @@ void() PlayerPreThink =
if (self.downed) {
self.maxspeed = 30;
} else {
self.maxspeed = 190;
// Walk slower to account for NZ:P Beta Scaling.
if (map_compatibility_mode == MAP_COMPAT_BETA)
self.maxspeed = 150;
else
self.maxspeed = 190;
if (self.sprinting) {
#ifdef FTE
@ -783,8 +864,16 @@ void() PlayerSpawn =
Player_PickSpawnPoint();
self.fixangle = true;
setsize(self, PLAYER_MINS_STANDING, PLAYER_MAXS_STANDING);
self.view_ofs = VEC_VIEW_OFS; // naievil -- set view_ofs to 32 to maintain half life (64) sizes
// NZ:P Beta used Quake BSP 29, so set bounding box accordingly.
if (map_compatibility_mode == MAP_COMPAT_BETA) {
self.view_ofs = VIEW_OFS_QK;
setsize(self, PLAYER_MINS_QUAKE, PLAYER_MAXS_QUAKE);
} else {
self.view_ofs = VIEW_OFS_HL;
setsize(self, PLAYER_MINS_STANDING, PLAYER_MAXS_STANDING);
}
self.stance = 2;
self.new_ofs_z = self.view_ofs_z;
self.oldz = self.origin_z;
@ -831,6 +920,8 @@ void() PlayerSpawn =
if (G_WORLDTEXT)
WorldText(world.chaptertitle, world.location, world.date, world.person, self);
ReportMapMode(map_compatibility_mode, self);
#else
self.Weapon_Name = GetWeaponName(self.weapon);

View file

@ -0,0 +1,525 @@
/*
server/utilities/map_compatibility.qc
Converts entities and other gameplay functions from earlier versions
of NZ:P to work here.
Copyright (C) 2021-2023 NZ:P Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
//
// NZ:P Beta Waypoints
//
//
// Compat_TryLoadBetaWaypoints()
// Called by FTE in LoadWaypointData(), if
// it can't find a traditional .way file, it'll
// look for an old one here.
//
#ifdef FTE
void() Compat_TryLoadBetaWaypoints =
{
// NZ:P Beta Waypoint files are simple, but contain redundant and
// hard to understand data. As far as I can gather both by interpretation
// and by reading aging source code, the structure for waypoints are as
// follows:
// <origin> : Origin of waypoint entity, always comes before all else.
// <id> : Starts at one, index/id of waypoint.
// <link1> : First Waypoint link ID, of four. Zero refers to a non-link.
// <link2> : Second Waypoint link ID, of four. Zero refers to a non-link.
// <link3> : Third Waypoint link ID, of four. Zero refers to a non-link.
// <link1> : Fourth Waypoint link ID, of four. Zero refers to a non-link.
// <owner1> : First marked "owner" ID, of four. Seems to only serve as a duplicate of links.
// <owner2> : Second marked "owner" ID, of four. Seems to only serve as a duplicate of links.
// <owner3> : Third marked "owner" ID, of four. Seems to only serve as a duplicate of links.
// <owner4> : Fourth marked "owner" ID, of four. Seems to only serve as a duplicate of links.
// File path refers to just "mapname" (no extension), the source port at
// the time always defaulted this to data/mapname.
float file_handle;
file_handle = fopen(mapname, FILE_READ);
if (file_handle == -1) {
dprint("Compat_TryLoadBetaWaypoints: No Beta waypoint data found.\n");
return;
}
float i;
// Clear all waypoints
for(i = 0; i < MAX_WAYPOINTS; i++) {
waypoints[i].id = -1;
for(float j = 0; j < 10; j++) {
waypoints[i].target_id[j] = -1;
}
}
string file_line;
vector way_origin;
float way_id;
float way_targets[4];
while(1) {
file_line = fgets(file_handle);
// End of file.
if (!file_line)
break;
way_origin = stov(file_line); // <origin>
file_line = fgets(file_handle);
way_id = stof(file_line); // <id>
// <link1> - <link4>, <owner1> - <owner4>
for(i = 0; i < 8; i++) {
file_line = fgets(file_handle);
if (i < 4) {
way_targets[i] = stof(file_line);
}
}
// Fill our data structure.
waypoint_ai waypoint;
waypoint = waypoints[way_id];
waypoints[way_id].id = way_id;
waypoints[way_id].org = way_origin;
if (waypoint_mode) {
entity new_way = spawn();
new_way.solid = SOLID_TRIGGER;
new_way.touch = creator_way_touch;
new_way.classname = "waypoint";
new_way.waynum = ftos(way_id);
new_way.targets[0] = ftos(way_targets[0]);
new_way.targets[1] = ftos(way_targets[1]);
new_way.targets[2] = ftos(way_targets[2]);
new_way.targets[3] = ftos(way_targets[3]);
setorigin(new_way, way_origin);
setmodel(new_way, "models/way/normal_way.spr");
}
for(i = 0; i < 4; i++) {
if (way_targets[i] > 0)
waypoints[way_id].target_id[i] = way_targets[i];
}
}
fclose(file_handle);
};
#endif // FTE
//
// NZ:P Beta Props
//
//
// Compat_ConvertPropScale(model_path, scale_factor)
// Does the dirty work for Compat_ConvertPropScaling().
//
void(string model_path, float scale_factor) Compat_ConvertPropScale =
{
entity props = find(world, model, model_path);
while(props != world) {
props.scale = scale_factor;
props = find(props, model, model_path);
}
};
//
// Compat_ConvertWorldModelScales()
// Scales down every weapon world model in
// mass.
//
void() Compat_ConvertWorldModelScales =
{
entity props = find(world, classname, "place_model");
while(props != world) {
// We only check the first path, this *technically* makes
// a nasty assumption no one used the viewmodels ever..
// which I damn sure hope is true, for the sake of that guy's sanity..
if (substring(props.model, 0, 15) == "models/weapons/") {
props.scale = 0.75;
}
props = find(props, classname, "place_model");
}
};
//
// Compat_ConvertPropScaling()
// A lot of props nowadays are larger than
// originally designed, so scale them back
// down.
//
void() Compat_ConvertPropScaling =
{
// Manual Tweaking
Compat_ConvertPropScale("models/props/sandbags.mdl", 0.88);
Compat_ConvertPropScale("models/props/lamp_oil.mdl", 0.75);
// Automatic
Compat_ConvertWorldModelScales();
};
//
// NZ:P Beta Wall Weapons
//
//
// Compat_ConvertBetaWallWeapons()
// NZ:P Beta used different weapon IDs to refer
// to weapon indexes, this fixes that.
//
void() Compat_ConvertBetaWallWeapons =
{
entity weapons;
weapons = find(world, classname, "buy_weapon");
while(weapons != world) {
switch(weapons.weapon) {
case 1: weapons.weapon = W_COLT; break;
case 64: weapons.weapon = W_RAY; break;
case 129: weapons.weapon = W_KAR_SCOPE; break;
case 130: weapons.weapon = W_BAR; break;
case 131: weapons.weapon = W_M1A1; break;
case 132: weapons.weapon = W_M2; break;
case 133: weapons.weapon = W_TESLA; break;
case 134: weapons.weapon = W_THOMPSON; break;
case 135: weapons.weapon = W_SAWNOFF; break;
case 136: weapons.weapon = W_PPSH; break;
case 137: weapons.weapon = W_DB; break;
case 138: weapons.weapon = W_KAR; break;
case 139: weapons.weapon = W_FG; break;
case 140: weapons.weapon = W_TRENCH; break;
case 141: weapons.weapon = W_MG; break;
case 142: weapons.weapon = W_GEWEHR; break;
case 143: weapons.weapon = W_BROWNING; break;
case 144: weapons.weapon = W_MP5K; break;
case 145: weapons.weapon = W_357; break;
case 146: weapons.weapon = W_M1; break;
case 147: weapons.weapon = W_BIATCH; break;
case 148: weapons.weapon = W_MP40; break;
case 149: weapons.weapon = W_PANZER; break;
case 150: weapons.weapon = W_PTRS; break;
case 153: weapons.weapon = W_BK; break;
case 154: weapons.weapon = W_STG; break;
case 155: weapons.weapon = W_BETTY; break;
case 156: weapons.weapon = W_GRENADE; break;
case 182: weapons.weapon = W_TYPE; break;
case 157: weapons.weapon = W_PORTER; break;
case 158: weapons.weapon = W_HEADCRACKER; break;
case 159: weapons.weapon = W_WIDOW; break;
case 160: weapons.weapon = W_WIDDER; break;
case 161: weapons.weapon = W_FIW; break;
case 162: weapons.weapon = W_WUNDER; break;
case 163: weapons.weapon = W_GIBS; break;
case 164: weapons.weapon = W_SNUFF; break;
case 165: weapons.weapon = W_REAPER; break;
case 166: weapons.weapon = W_BORE; break;
case 167: weapons.weapon = W_ARMAGEDDON; break;
case 168: weapons.weapon = W_IMPELLER; break;
case 169: weapons.weapon = W_GUT; break;
case 170: weapons.weapon = W_BARRACUDA; break;
case 171: weapons.weapon = W_COMPRESSOR; break;
case 172: weapons.weapon = W_ACCELERATOR; break;
case 173: weapons.weapon = W_KILLU; break;
case 174: weapons.weapon = W_KOLLIDER; break;
case 175: weapons.weapon = W_M1000; break;
case 176: weapons.weapon = W_AFTERBURNER; break;
case 177: weapons.weapon = W_LONGINUS; break;
case 178: weapons.weapon = W_PENETRATOR; break;
case 179: weapons.weapon = W_KRAUS; break;
case 180: weapons.weapon = W_SPATZ; break;
case 181: weapons.weapon = W_BOWIE; break;
case 183: weapons.weapon = W_SAMURAI; break;
default: break;
}
weapons = find(weapons, classname, "buy_weapon");
}
};
//
// NZ:P Beta Barricades
//
//
// Compat_ConvertBetaBarricade
// Barricades need relocated, scaled,
// and their goal boxes re-positioned.
//
void() Compat_ConvertBetaBarricade =
{
makevectors(self.angles);
self.origin += v_up*48;
self.origin -= v_forward*2;
setsize(self, '-30 -30 -10','30 30 10');
self.box1 = self.origin + (v_forward * -50) + (v_up * -50);
self.box2 = self.box1 + (v_right * 25);
self.box3 = self.box1 + (v_right * -25);
self.idlebox = self.box1 + (v_forward * -50);
self.hop_spot = self.origin + v_forward * 50;
self.hop_spot_x -= 5;
self.hop_spot_z -= 20;
self.scale = 0.75;
};
void() item_cover = {map_compatibility_mode = MAP_COMPAT_BETA; item_barricade(); Compat_ConvertBetaBarricade();};
//
// NZ:P Beta Mystery Box
//
//
// Compat_FixMysteryBox
// Fixes the Mystery Box scale, and removes glow from
// all of the spawn points.
//
void() Compat_FixMysteryBox =
{
entity mystery_box = find(world, classname, "mystery");
while(mystery_box != world) {
mystery_box.scale = 0.75;
mystery_box.spawnflags += MBOX_SPAWNFLAG_NOLIGHT;
if (mystery_box.goaldummy) {
MBOX_FreeEnt(mystery_box.goaldummy);
mystery_box.goaldummy = world;
}
mystery_box = find(mystery_box, classname, "mystery");
}
entity mystery_box_spots = find(world, classname, "mystery_box_tp_spot");
while(mystery_box_spots != world) {
mystery_box_spots.spawnflags += MBOX_SPAWNFLAG_NOLIGHT;
mystery_box_spots = find(mystery_box_spots, classname, "mystery_box_tp_spot");
}
};
//
// NZ:P Beta Power Switch
//
//
// Compat_FixPowerSwitch
// Power Switches had the same classname as they
// do now, so we need to iterate over the world
// and modify their scale and origin.
//
void() Compat_FixPowerSwitch =
{
entity power_switches = find(world, classname, "power_switch");
while(power_switches != world) {
makevectors(power_switches.angles);
power_switches.scale = 0.88;
power_switches.origin += v_up*6;
power_switches.origin += v_forward*10;
power_switches = find(power_switches, classname, "power_switch");
}
};
//
// NZ:P Beta Perk-A-Cola Machines
//
//
// Compat_RelocateBetaPerkMachine()
// Perk-A-Cola models in NZ:P Beta used to have
// non-center origin offsets, so they need re-placed
// to be (nearly) matching what they were intended to be.
// This also sets the scaling correctly, sue me.
//
#define COMPAT_RELOCAT_NORM 0
#define COMPAT_RELOCAT_PAP 1
#define COMPAT_RELOCAT_SPEED 2
void(float mode) Compat_RelocateBetaPerkMachine =
{
makevectors(self.angles);
switch(mode) {
case COMPAT_RELOCAT_PAP:
self.origin += v_forward*8;
self.origin += v_up*24;
break;
case COMPAT_RELOCAT_SPEED:
self.origin += v_forward*17;
self.origin += v_up*2;
break;
default:
self.origin += v_forward*10;
self.origin += v_up*4;
break;
}
self.scale = 0.85;
};
void() item_revive = {map_compatibility_mode = MAP_COMPAT_BETA; Compat_RelocateBetaPerkMachine(COMPAT_RELOCAT_NORM); perk_revive();};
void() item_speed = {map_compatibility_mode = MAP_COMPAT_BETA; Compat_RelocateBetaPerkMachine(COMPAT_RELOCAT_SPEED); perk_speed();};
void() item_flopper = {map_compatibility_mode = MAP_COMPAT_BETA; Compat_RelocateBetaPerkMachine(COMPAT_RELOCAT_NORM); perk_flopper();};
void() item_juggernog = {map_compatibility_mode = MAP_COMPAT_BETA; Compat_RelocateBetaPerkMachine(COMPAT_RELOCAT_NORM); perk_juggernog();};
void() item_douple = {map_compatibility_mode = MAP_COMPAT_BETA; Compat_RelocateBetaPerkMachine(COMPAT_RELOCAT_NORM); perk_double(); self.spawnflags += PERK_SPAWNFLAG_DOUBLETAPV1;};
void() item_staminup = {map_compatibility_mode = MAP_COMPAT_BETA; Compat_RelocateBetaPerkMachine(COMPAT_RELOCAT_NORM); perk_staminup();};
void() item_pap = {map_compatibility_mode = MAP_COMPAT_BETA; Compat_RelocateBetaPerkMachine(COMPAT_RELOCAT_PAP); perk_pap();};
//
// NZ:P Beta Triggers
//
#ifdef FTE
//
// Compat_TriggerCommandIsSafe()
// Pass a trigger_command .message to this,
// it's a whitelist that determines whether
// or not we should let the map use this.
//
float(string msg) Compat_TriggerCommandIsSafe =
{
// First check: Don't allow multiple commands, at all. So
// fail if there's a ';' anywhere.
for(float i = 0; i < strlen(msg) - 1; i++) {
if (substring(msg, i, i + 1) == ";")
return false;
}
// Allow playing audio and whatnot.
if (substring(msg, 0, 4) != "play")
return false;
return true;
};
void() touch_command =
{
if (other.classname != "player" || self.electro_targeted)
return;
self.electro_targeted = true;
// Follow up with cl_insta because whoever wrote this way back
// forgot to perform a line break..
stuffcmd(other, strcat(self.message, "cl_insta\n"));
};
#endif // FTE
//
// trigger_command
// Whoever was behind this was nasty...
// on contact, this trigger runs a stuffcmd()
// to the touching client. Obviously, this can't
// fly.
//
void() trigger_command =
{
map_compatibility_mode = MAP_COMPAT_BETA;
#ifdef FTE
// If there's no message, or the message
// is invalid, remove this garbage.
if (!self.message || !Compat_TriggerCommandIsSafe(self.message)) {
return;
}
InitTrigger();
self.touch = touch_command;
#else
remove(self);
#endif // FTE
};
//
// General NZ:P Compatibility
//
//
// Compat_ConvertOldAssetPath(path)
// Takes in a path as a string, hashes it,
// then performs a binary search to pick
// a redirected (updated) path.
//
string(string path) Compat_ConvertOldAssetPath =
{
string return_string = path;
// Generate a CRC16 IBM 3740 hash of the path
float input_hash = crc16(true, path);
float input_len = strlen(path); // Assists with hash collision detection.
// Perform the binary search to locate it
float bs_left = 0;
float bs_right = asset_conversion_table.length - 1;
while(bs_left <= bs_right) {
float bs_middle = (bs_left + bs_right) / 2;
bs_middle = bs_middle & ~0;
if (asset_conversion_table[bs_middle].old_path_crc == input_hash && asset_conversion_table[bs_middle].crc_strlen == input_len) {
return_string = asset_conversion_table[bs_middle].current_path;
break;
}
if (asset_conversion_table[bs_middle].old_path_crc < input_hash)
bs_left = bs_middle + 1;
else
bs_right = bs_middle - 1;
}
return return_string;
};
//
// Compat_Init()
// Called as soon as the server spawns in
// a client, does more conversion for
// map compatibility that cannot just be
// done in QC logic or in spawn functions.
//
void() Compat_Init =
{
if (map_compatibility_mode != MAP_COMPAT_BETA)
return;
Compat_ConvertBetaWallWeapons();
Compat_ConvertPropScaling();
Compat_FixPowerSwitch();
Compat_FixMysteryBox();
};

View file

@ -821,15 +821,15 @@ void(float damage, vector dir, vector org, vector plane, entity hit_ent, float s
self = oldself;
return;
} else if (hit_ent.classname == "door" || hit_ent.classname == "door_nzp") {
local entity old;
old = self;
} else if (hit_ent.solid == SOLID_BSP) {
oldself = self;
self = hit_ent;
self.health -= damage;
self.enemy = oldself;
if (self.health < 0)
door_use();
self = old;
self.th_die();
self = oldself;
return;
}
@ -1528,46 +1528,31 @@ void() Change_Stance = {
return;
switch(self.stance) {
case 2:
self.new_ofs_z = self.view_ofs_z - PLAYER_CROUCH_HEIGHT;
self.stance = 1;
PAnim_Crouch();
setsize(self, PLAYER_MINS_CROUCHING, PLAYER_MAXS_CROUCHING);
case PLAYER_STANCE_STAND:
Player_SetStance(self, PLAYER_STANCE_CROUCH, true);
break;
case 1:
// Prohibit Proning if Drinking a Perk-A-Cola
if (self.isBuying && Player_CanStandHere(self)) {
self.stance = 2;
self.new_ofs_z = self.view_ofs_z + PLAYER_CROUCH_HEIGHT;
PAnim_Stand();
setsize(self, PLAYER_MINS_STANDING, PLAYER_MAXS_STANDING);
// Prohibit Proning if Drinking a Perk-A-Cola, just stand.
if (self.isBuying) {
Player_SetStance(self, PLAYER_STANCE_STAND, true);
}
// Stance flag isn't set, so go Prone.
else if (!self.stancereset) {
self.new_ofs_z = self.view_ofs_z - PLAYER_PRONE_HEIGHT;
self.stance = 0;
PAnim_Prone();
Player_SetStance(self, PLAYER_STANCE_PRONE, true);
}
// Stance flag IS set, so stand if applicable.
else if (Player_CanStandHere(self)) {
self.new_ofs_z = self.view_ofs_z + PLAYER_CROUCH_HEIGHT;
self.stance = 2;
self.stancereset = 0;
PAnim_Stand();
setsize(self, PLAYER_MINS_STANDING, PLAYER_MAXS_STANDING);
Player_SetStance(self, PLAYER_STANCE_STAND, true);
self.stancereset = false;
}
// There's no room to stand, just prone again.
else {
self.new_ofs_z = self.view_ofs_z - PLAYER_PRONE_HEIGHT;
self.stance = 0;
PAnim_Prone();
Player_SetStance(self, PLAYER_STANCE_PRONE, true);
}
break;
case 0:
self.new_ofs_z = self.view_ofs_z + PLAYER_PRONE_HEIGHT;
self.stance = self.stancereset = 1;
setsize(self, PLAYER_MINS_CROUCHING, PLAYER_MAXS_CROUCHING);
PAnim_UpCrouch();
Player_SetStance(self, PLAYER_STANCE_CROUCH, true);
self.stancereset = true;
break;
default: break;
}
@ -1576,7 +1561,10 @@ void() Change_Stance = {
void() dolphin_dive = //naievil
{
if (self.stance != 2 || self.view_ofs_z != 32)
if (self.stance != 2)
return;
if ((map_compatibility_mode == MAP_COMPAT_BETA && self.view_ofs_z != VIEW_OFS_QK[2]) ||
(!map_compatibility_mode && self.view_ofs_z != VIEW_OFS_HL[2]))
return;
if (self.flags & FL_WATERJUMP)
return;
@ -1614,9 +1602,7 @@ void() dolphin_dive = //naievil
sound(self, CHAN_VOICE, "sounds/player/jump.wav", 1, 1);
self.oldz = self.origin_z;
self.new_ofs_z = self.view_ofs_z - (PLAYER_CROUCH_HEIGHT + PLAYER_PRONE_HEIGHT);
self.stance = 0;
setsize(self, PLAYER_MINS_CROUCHING, PLAYER_MAXS_CROUCHING);
Player_SetStance(self, PLAYER_STANCE_PRONE, false);
}
@ -1651,19 +1637,8 @@ void () Impulse_Functions =
if (self.dive || self.downed || !Player_CanStandHere(self))
return;
switch(self.stance) {
case 0:
self.new_ofs_z = self.view_ofs_z + PLAYER_CROUCH_HEIGHT + PLAYER_PRONE_HEIGHT;
self.stance = 2;
setsize(self, PLAYER_MINS_STANDING, PLAYER_MAXS_STANDING);
break;
case 1:
self.new_ofs_z = self.view_ofs_z + PLAYER_CROUCH_HEIGHT;
self.stance = 2;
setsize(self, PLAYER_MINS_STANDING, PLAYER_MAXS_STANDING);
break;
default: break;
}
Player_SetStance(self, PLAYER_STANCE_STAND, false);
self.sprintflag = true;
W_SprintStart();
break;

View file

@ -62,6 +62,7 @@ const float EVENT_CHATMESSAGE = 45;
const float EVENT_DOUBLETAPUPDATE = 46;
const float EVENT_FLAME = 47;
const float EVENT_ENDGAME = 48;
const float EVENT_MAPTYPE = 49;
// Define our FTE platform
#ifndef STANDARD
@ -73,10 +74,22 @@ const float EVENT_ENDGAME = 48;
#define PLAYER_MINS_STANDING '-16 -16 -32'
#define PLAYER_MAXS_STANDING '16 16 40'
// 32x32x56
#define PLAYER_MINS_QUAKE '-16 -16 -24'
#define PLAYER_MAXS_QUAKE '16 16 32'
// 32x32x36
#define PLAYER_MINS_CROUCHING '-16 -16 -32'
#define PLAYER_MAXS_CROUCHING '16 16 4'
#define PLAYER_STANCE_STAND 2
#define PLAYER_STANCE_CROUCH 1
#define PLAYER_STANCE_PRONE 0
// map compatibility
#define MAP_COMPAT_BETA 1
float map_compatibility_mode;
// Weapon Firetype definitions
#define FIRETYPE_FULLAUTO 0
#define FIRETYPE_SEMIAUTO 1

View file

@ -0,0 +1,111 @@
old_path,current_path
progs/player.mdl,models/player.mdl
progs/ai/zal(.mdl,models/ai/zal(.mdl
models/machines/quick_revive.mdl,models/machines/quake_scale/quick_revive.mdl
models/machines/juggernog.mdl,models/machines/quake_scale/juggernog.mdl
models/machines/speed_cola.mdl,models/machines/quake_scale/speed_cola.mdl
progs/misc/double_tap.mdl,models/machines/quake_scale/double_tap.mdl
models/machines/double_tap.mdl,models/machines/quake_scale/double_tap.mdl
progs/misc/flopper.mdl,models/machines/quake_scale/flopper.mdl
models/machines/flopper.mdl,models/machines/quake_scale/flopper.mdl
models/machines/staminup.mdl,models/machines/quake_scale/staminup.mdl
models/machines/deadshot.mdl,models/machines/quake_scale/deadshot.mdl
models/machines/mulekick.mdl,models/machines/quake_scale/mulekick.mdl
progs/misc/pap.mdl,models/machines/quake_scale/pap.mdl
models/machines/pap.mdl,models/machines/quake_scale/pap.mdl
progs/sprites/lamp_glow.spr,models/sprites/lamp_glow.spr
progs/sprites/lamp_glow3.spr,models/sprites/lamp_glow.spr
progs/props/kino_boxes2.mdl,models/props/Kino_boxes2.mdl
progs/props/kino_boxes3.mdl,models/props/Kino_boxes3.mdl
progs/props/kino_boxes4.mdl,models/props/Kino_boxes4.mdl
progs/body_bag_flat.mdl,models/props/bodybag_flat.mdl
progs/body_bag_head.mdl,models/props/bodybag_head.mdl
progs/body_bag_back_wall.mdl,models/props/bodybag_back_wall.mdl
progs/teddy.mdl,models/props/teddy.mdl
progs/props/teddy.mdl,models/props/teddy.mdl
progs/misc/teddy.mdl,models/props/teddy.mdl
progs/props/kino_box.mdl,models/props/Kino_box.mdl
progs/props/table_dinner.mdl,models/props/table_dinner.mdl
progs/props/table_sq.mdl,models/props/table_sq.mdl
progs/props/rebar.mdl,models/props/rebar.mdl
progs/props/kino_table.mdl,models/props/Kino_table.mdl
progs/props/kino_couch.mdl,models/props/kino_couch.mdl
progs/props/metal_chair.mdl,models/props/metal_chair.mdl
progs/props/sandbags.mdl,models/props/sandbags.mdl
progs/sandbags.mdl,models/props/sandbags.mdl
progs/dentist_chair.mdl,models/props/dentist_chair.mdl
progs/props/dentist_chair.mdl,models/props/dentist_chair.mdl
progs/props/bath.mdl,models/props/bath.mdl
progs/props/shelf.mdl,models/props/shelf.mdl
progs/props/dummy.mdl,models/props/dummy.mdl
progs/props/stand.mdl,models/props/stand.mdl
progs/props/radio.mdl,models/props/radio.mdl
progs/props/radiator.mdl,models/props/radiator.mdl
progs/props/lamp_ndu.mdl,models/props/lamp_ndu.mdl
progs/props/lamp_ndu45.mdl,models/props/lamp_ndu45.mdl
progs/jeep.mdl,models/props/jeep.mdl
progs/tree.mdl,models/props/treeth.mdl
progs/treef.mdl,models/props/tree_swamp.mdl
progs/props/barrel_m.mdl,models/props/barrel_m.mdl
progs/props/lamp_oil.mdl,models/props/lamp_oil.mdl
progs/props/piano.mdl,models/props/piano.mdl
progs/props/pisuar.mdl,models/props/pisuar.mdl
progs/props/teleporter.mdl,models/props/teleporter.mdl
progs/props/chandelier.mdl,models/props/chandelier.mdl
progs/props/vanity_table.mdl,models/props/vanity_table.mdl
progs/props/trash_con.mdl,models/props/trash_con.mdl
progs/flame2.mdl,models/props/flame.mdl
progs/toilet.mdl,models/props/toilet.mdl
progs/fridge.mdl,models/props/fridge.mdl
progs/props/fridge.mdl,models/props/fridge.mdl
progs/props/kino_chairset.mdl,models/props/kino_chairset.mdl
progs/props/kino_lounge.mdl,models/props/Kino_lounge.mdl
progs/props/kino_stageprop.mdl,models/props/kino_stageprop.mdl
progs/props/mainframe_pad.mdl,models/props/mainframe_pad.mdl
progs/props/tree_ch.mdl,models/props/tree_ch.mdl
progs/props/treesl.mdl,models/props/treesl.mdl
progs/lamp.mdl,models/props/lamp_oil.mdl
progs/props/bed.mdl,models/props/bed.mdl
progs/gmodels/g_mp40.mdl,models/weapons/mp40/g_mp40.mdl
progs/g_mp40.mdl,models/weapons/mp40/g_mp40.mdl
progs/gmodels/g_thomp.mdl,models/weapons/thomp/g_thomp.mdl
progs/g_thomp.mdl,models/weapons/thomp/g_thomp.mdl
progs/gmodels/g_betty.mdl,models/weapons/grenade/g_betty.mdl
progs/g_betty.mdl,models/weapons/grenade/g_betty.mdl
progs/g_fg.mdl,models/weapons/fg42/g_fg.mdl
progs/gmodels/g_fg.mdl,models/weapons/fg42/g_fg.mdl
progs/g_m1a1.mdl,models/weapons/m1carbine/g_m1a1.mdl
progs/g_ray.mdl,models/weapons/ray/g_ray.mdl
progs/g_tesla.mdl,models/weapons/tesla/g_tesla.mdl
progs/g_mg.mdl,models/weapons/mg/g_mg.mdl
progs/g_colt.mdl,models/weapons/m1911/g_colt.mdl
progs/g_browning.mdl,models/weapons/browning/g_browning.mdl
progs/g_m1.mdl,models/weapons/garand/g_m1.mdl
progs/gmodels/g_m1.mdl,models/weapons/garand/g_m1.mdl
progs/g_sawn.mdl,models/weapons/sawnoff/g_sawnoff.mdl
progs/gmodels/g_sawnoff.mdl,models/weapons/sawnoff/g_sawnoff.mdl
progs/g_trench.mdl,models/weapons/trench/g_trench.mdl
progs/gmodels/g_trench.mdl,models/weapons/trench/g_trench.mdl
progs/gmodels/g_bar.mdl,models/weapons/bar/g_bar.mdl
progs/grenade.mdl,models/weapons/grenade/g_grenade.mdl
progs/gmodels/g_grenade.mdl,models/weapons/grenade/g_grenade.mdl
progs/g_gewehr.mdl,models/weapons/gewehr/g_gewehr.mdl
progs/gmodels/g_gewehr.mdl,models/weapons/gewehr/g_gewehr.mdl
progs/g_db.mdl,models/weapons/db/g_db.mdl
progs/g_kar.mdl,models/weapons/kar/g_kar.mdl
progs/g_kars.mdl,models/weapons/kar/g_kars.mdl
progs/g_bowie.mdl,models/weapons/knife/g_bowie.mdl
progs/gmodels/g_bowie.mdl,models/weapons/knife/g_bowie.mdl
progs/g_mp5.mdl,models/weapons/mp5k/g_mp5k.mdl
progs/gmodels/g_type.mdl,models/weapons/type/g_type.mdl
progs/gmodels/g_ppsh.mdl,models/weapons/ppsh/g_ppsh.mdl
progs/g_ppsh.mdl,models/weapons/ppsh/g_ppsh.mdl
progs/gmodels/g_stg.mdl,models/weapons/stg/g_stg.mdl
progs/g_stg.mdl,models/weapons/stg/g_stg.mdl
models/misc/lightning.spr,models/sprites/lightning.spr
models/derped/wall_lamp.mdl,models/props/lamp_wall.mdl
models/machines/power_switch.mdl,models/machines/quake_scale/power_switch.mdl
models/machines/hl_scale/packapunch/p_machine.mdl,models/machines/hl_scale/pap/p_machine.mdl
models/machines/hl_scale/packapunch/p_roller.mdl,models/machines/hl_scale/pap/p_roller.mdl
models/machines/hl_scale/packapunch/p_flag.mdl,models/machines/hl_scale/pap/p_flag.mdl
progs/sprites/lamp_glow2.spr,models/sprites/lamp_glow2.spr
1 old_path current_path
2 progs/player.mdl models/player.mdl
3 progs/ai/zal(.mdl models/ai/zal(.mdl
4 models/machines/quick_revive.mdl models/machines/quake_scale/quick_revive.mdl
5 models/machines/juggernog.mdl models/machines/quake_scale/juggernog.mdl
6 models/machines/speed_cola.mdl models/machines/quake_scale/speed_cola.mdl
7 progs/misc/double_tap.mdl models/machines/quake_scale/double_tap.mdl
8 models/machines/double_tap.mdl models/machines/quake_scale/double_tap.mdl
9 progs/misc/flopper.mdl models/machines/quake_scale/flopper.mdl
10 models/machines/flopper.mdl models/machines/quake_scale/flopper.mdl
11 models/machines/staminup.mdl models/machines/quake_scale/staminup.mdl
12 models/machines/deadshot.mdl models/machines/quake_scale/deadshot.mdl
13 models/machines/mulekick.mdl models/machines/quake_scale/mulekick.mdl
14 progs/misc/pap.mdl models/machines/quake_scale/pap.mdl
15 models/machines/pap.mdl models/machines/quake_scale/pap.mdl
16 progs/sprites/lamp_glow.spr models/sprites/lamp_glow.spr
17 progs/sprites/lamp_glow3.spr models/sprites/lamp_glow.spr
18 progs/props/kino_boxes2.mdl models/props/Kino_boxes2.mdl
19 progs/props/kino_boxes3.mdl models/props/Kino_boxes3.mdl
20 progs/props/kino_boxes4.mdl models/props/Kino_boxes4.mdl
21 progs/body_bag_flat.mdl models/props/bodybag_flat.mdl
22 progs/body_bag_head.mdl models/props/bodybag_head.mdl
23 progs/body_bag_back_wall.mdl models/props/bodybag_back_wall.mdl
24 progs/teddy.mdl models/props/teddy.mdl
25 progs/props/teddy.mdl models/props/teddy.mdl
26 progs/misc/teddy.mdl models/props/teddy.mdl
27 progs/props/kino_box.mdl models/props/Kino_box.mdl
28 progs/props/table_dinner.mdl models/props/table_dinner.mdl
29 progs/props/table_sq.mdl models/props/table_sq.mdl
30 progs/props/rebar.mdl models/props/rebar.mdl
31 progs/props/kino_table.mdl models/props/Kino_table.mdl
32 progs/props/kino_couch.mdl models/props/kino_couch.mdl
33 progs/props/metal_chair.mdl models/props/metal_chair.mdl
34 progs/props/sandbags.mdl models/props/sandbags.mdl
35 progs/sandbags.mdl models/props/sandbags.mdl
36 progs/dentist_chair.mdl models/props/dentist_chair.mdl
37 progs/props/dentist_chair.mdl models/props/dentist_chair.mdl
38 progs/props/bath.mdl models/props/bath.mdl
39 progs/props/shelf.mdl models/props/shelf.mdl
40 progs/props/dummy.mdl models/props/dummy.mdl
41 progs/props/stand.mdl models/props/stand.mdl
42 progs/props/radio.mdl models/props/radio.mdl
43 progs/props/radiator.mdl models/props/radiator.mdl
44 progs/props/lamp_ndu.mdl models/props/lamp_ndu.mdl
45 progs/props/lamp_ndu45.mdl models/props/lamp_ndu45.mdl
46 progs/jeep.mdl models/props/jeep.mdl
47 progs/tree.mdl models/props/treeth.mdl
48 progs/treef.mdl models/props/tree_swamp.mdl
49 progs/props/barrel_m.mdl models/props/barrel_m.mdl
50 progs/props/lamp_oil.mdl models/props/lamp_oil.mdl
51 progs/props/piano.mdl models/props/piano.mdl
52 progs/props/pisuar.mdl models/props/pisuar.mdl
53 progs/props/teleporter.mdl models/props/teleporter.mdl
54 progs/props/chandelier.mdl models/props/chandelier.mdl
55 progs/props/vanity_table.mdl models/props/vanity_table.mdl
56 progs/props/trash_con.mdl models/props/trash_con.mdl
57 progs/flame2.mdl models/props/flame.mdl
58 progs/toilet.mdl models/props/toilet.mdl
59 progs/fridge.mdl models/props/fridge.mdl
60 progs/props/fridge.mdl models/props/fridge.mdl
61 progs/props/kino_chairset.mdl models/props/kino_chairset.mdl
62 progs/props/kino_lounge.mdl models/props/Kino_lounge.mdl
63 progs/props/kino_stageprop.mdl models/props/kino_stageprop.mdl
64 progs/props/mainframe_pad.mdl models/props/mainframe_pad.mdl
65 progs/props/tree_ch.mdl models/props/tree_ch.mdl
66 progs/props/treesl.mdl models/props/treesl.mdl
67 progs/lamp.mdl models/props/lamp_oil.mdl
68 progs/props/bed.mdl models/props/bed.mdl
69 progs/gmodels/g_mp40.mdl models/weapons/mp40/g_mp40.mdl
70 progs/g_mp40.mdl models/weapons/mp40/g_mp40.mdl
71 progs/gmodels/g_thomp.mdl models/weapons/thomp/g_thomp.mdl
72 progs/g_thomp.mdl models/weapons/thomp/g_thomp.mdl
73 progs/gmodels/g_betty.mdl models/weapons/grenade/g_betty.mdl
74 progs/g_betty.mdl models/weapons/grenade/g_betty.mdl
75 progs/g_fg.mdl models/weapons/fg42/g_fg.mdl
76 progs/gmodels/g_fg.mdl models/weapons/fg42/g_fg.mdl
77 progs/g_m1a1.mdl models/weapons/m1carbine/g_m1a1.mdl
78 progs/g_ray.mdl models/weapons/ray/g_ray.mdl
79 progs/g_tesla.mdl models/weapons/tesla/g_tesla.mdl
80 progs/g_mg.mdl models/weapons/mg/g_mg.mdl
81 progs/g_colt.mdl models/weapons/m1911/g_colt.mdl
82 progs/g_browning.mdl models/weapons/browning/g_browning.mdl
83 progs/g_m1.mdl models/weapons/garand/g_m1.mdl
84 progs/gmodels/g_m1.mdl models/weapons/garand/g_m1.mdl
85 progs/g_sawn.mdl models/weapons/sawnoff/g_sawnoff.mdl
86 progs/gmodels/g_sawnoff.mdl models/weapons/sawnoff/g_sawnoff.mdl
87 progs/g_trench.mdl models/weapons/trench/g_trench.mdl
88 progs/gmodels/g_trench.mdl models/weapons/trench/g_trench.mdl
89 progs/gmodels/g_bar.mdl models/weapons/bar/g_bar.mdl
90 progs/grenade.mdl models/weapons/grenade/g_grenade.mdl
91 progs/gmodels/g_grenade.mdl models/weapons/grenade/g_grenade.mdl
92 progs/g_gewehr.mdl models/weapons/gewehr/g_gewehr.mdl
93 progs/gmodels/g_gewehr.mdl models/weapons/gewehr/g_gewehr.mdl
94 progs/g_db.mdl models/weapons/db/g_db.mdl
95 progs/g_kar.mdl models/weapons/kar/g_kar.mdl
96 progs/g_kars.mdl models/weapons/kar/g_kars.mdl
97 progs/g_bowie.mdl models/weapons/knife/g_bowie.mdl
98 progs/gmodels/g_bowie.mdl models/weapons/knife/g_bowie.mdl
99 progs/g_mp5.mdl models/weapons/mp5k/g_mp5k.mdl
100 progs/gmodels/g_type.mdl models/weapons/type/g_type.mdl
101 progs/gmodels/g_ppsh.mdl models/weapons/ppsh/g_ppsh.mdl
102 progs/g_ppsh.mdl models/weapons/ppsh/g_ppsh.mdl
103 progs/gmodels/g_stg.mdl models/weapons/stg/g_stg.mdl
104 progs/g_stg.mdl models/weapons/stg/g_stg.mdl
105 models/misc/lightning.spr models/sprites/lightning.spr
106 models/derped/wall_lamp.mdl models/props/lamp_wall.mdl
107 models/machines/power_switch.mdl models/machines/quake_scale/power_switch.mdl
108 models/machines/hl_scale/packapunch/p_machine.mdl models/machines/hl_scale/pap/p_machine.mdl
109 models/machines/hl_scale/packapunch/p_roller.mdl models/machines/hl_scale/pap/p_roller.mdl
110 models/machines/hl_scale/packapunch/p_flag.mdl models/machines/hl_scale/pap/p_flag.mdl
111 progs/sprites/lamp_glow2.spr models/sprites/lamp_glow2.spr

View file

@ -1,24 +1,22 @@
#!/usr/bin/env bash
cd ../
# generate hash table
echo "Generating Hash Table.."
python bin/qc_hash_generator.py -i tools/asset_conversion_table.csv -o source/server/hash_table.qc
# create build directories
mkdir -p build/{fte,standard}
cd bin/
echo ""
echo "========================"
echo " compiling FTE CCQC "
echo "========================"
echo ""
./fteqcc-cli-lin -srcfile ../progs/fte-client.src
echo ""
echo "========================"
echo " compiling FTE SSQC "
echo "========================"
echo ""
./fteqcc-cli-lin -O2 -srcfile ../progs/fte-server.src
echo ""
echo "========================"
echo " compiling STANDARD QC "
echo "========================"
echo ""
./fteqcc-cli-lin -O2 -srcfile ../progs/standard.src
# build..
echo "Compiling FTE CSQC.."
./fteqcc-cli-lin -srcfile ../progs/fte-client.src | grep -E -i "warning |error |defined |not |unknown"
echo "Compiling FTE SSQC.."
./fteqcc-cli-lin -O2 -srcfile ../progs/fte-server.src | grep -E -i "warning |error |defined |not |unknown"
echo "Compiling Standard/Id SSQC.."
./fteqcc-cli-lin -O2 -srcfile ../progs/standard.src | grep -E -i "warning |error |defined |not |unknown"
echo "End of script."

View file

@ -1,24 +1,22 @@
#!/usr/bin/env bash
cd ../
# generate hash table
echo "Generating Hash Table.."
python bin/qc_hash_generator.py -i tools/asset_conversion_table.csv -o source/server/hash_table.qc
# create build directories
mkdir -p build/{fte,standard}
cd bin/
echo ""
echo "========================"
echo " compiling FTE CCQC "
echo "========================"
echo ""
./fteqcc-cli-mac -srcfile ../progs/fte-client.src
echo ""
echo "========================"
echo " compiling FTE SSQC "
echo "========================"
echo ""
./fteqcc-cli-mac -O2 -srcfile ../progs/fte-server.src
echo ""
echo "========================"
echo " compiling STANDARD QC "
echo "========================"
echo ""
./fteqcc-cli-mac -O2 -srcfile ../progs/standard.src
# build..
echo "Compiling FTE CSQC.."
./fteqcc-cli-mac -srcfile ../progs/fte-client.src | grep -E -i "warning |error |defined |not |unknown"
echo "Compiling FTE SSQC.."
./fteqcc-cli-mac -O2 -srcfile ../progs/fte-server.src | grep -E -i "warning |error |defined |not |unknown"
echo "Compiling Standard/Id SSQC.."
./fteqcc-cli-mac -O2 -srcfile ../progs/standard.src | grep -E -i "warning |error |defined |not |unknown"
echo "End of script."

View file

@ -1,25 +1,24 @@
@ECHO OFF
CD ../
REM ****** generate hash table ******
echo Generating Hash Table..
python bin\qc_hash_generator.py -i tools\asset_conversion_table.csv -o source\server\hash_table.qc
REM ****** create build directories ******
MKDIR build\fte\ 2>nul
MKDIR build\standard\ 2>nul
CD bin/
echo.
echo ========================
echo compiling FTE CCQC
echo ========================
echo.
REM ****** build.. ******
echo Compiling FTE CSQC..
fteqcc-cli-win.exe -srcfile ../progs/fte-client.src
echo.
echo ========================
echo compiling FTE SSQC
echo ========================
echo.
echo Compiling FTE SSQC..
fteqcc-cli-win.exe -O2 -srcfile ../progs/fte-server.src
echo.
echo ========================
echo compiling STANDARD QC
echo ========================
echo.
echo Compiling Standard/Id SSQC..
fteqcc-cli-win.exe -O2 -srcfile ../progs/standard.src
pause
echo End of script.
pause