mirror of
https://github.com/nzp-team/quakec.git
synced 2024-11-26 05:41:20 +00:00
SERVER: Major Mystery Box Revamp, add support for MBOX2 format
This commit is contained in:
parent
5d392899bb
commit
ea90417314
8 changed files with 504 additions and 272 deletions
|
@ -945,11 +945,11 @@ void(float width, float height) HUD_Useprint =
|
||||||
usestring = strcat("Hold ",usespace, " to Rebuild Barrier");
|
usestring = strcat("Hold ",usespace, " to Rebuild Barrier");
|
||||||
break;
|
break;
|
||||||
case 6://box
|
case 6://box
|
||||||
usestring = strcat("Hold ",usespace, " to buy a Random Weapon");
|
usestring = strcat("Hold ",usespace, " for Mystery Box");
|
||||||
usecost = strcat("[Cost:", ftos(useprint_cost), "]");
|
usecost = strcat("[Cost:", ftos(useprint_cost), "]");
|
||||||
break;
|
break;
|
||||||
case 7://box take
|
case 7://box take
|
||||||
usestring = strcat("Hold ",usespace, " to take Weapon");
|
usestring = strcat("Hold ",usespace, " for ", GetWeaponName(useprint_weapon));
|
||||||
break;
|
break;
|
||||||
case 8://power
|
case 8://power
|
||||||
usestring = "The Power must be Activated first";
|
usestring = "The Power must be Activated first";
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
put custom server-only globals and fields here
|
put custom server-only globals and fields here
|
||||||
|
|
||||||
Copyright (C) 2021-2022 NZ:P Team
|
Copyright (C) 2021-2023 NZ:P Team
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
@ -66,7 +66,6 @@ void(string com) SV_ParseClientCommand;
|
||||||
float ach_tracker_col2;
|
float ach_tracker_col2;
|
||||||
float ach_tracker_barr;
|
float ach_tracker_barr;
|
||||||
float ach_tracker_spin;
|
float ach_tracker_spin;
|
||||||
float ach_tracker_luck;
|
|
||||||
|
|
||||||
float global_trace_damage_multiplier;
|
float global_trace_damage_multiplier;
|
||||||
|
|
||||||
|
@ -396,14 +395,30 @@ float isPowerOn;
|
||||||
.float revivesoda;
|
.float revivesoda;
|
||||||
.float collected;
|
.float collected;
|
||||||
|
|
||||||
.float boxstatus;
|
// Mystery Box
|
||||||
|
#define MAX_BOX_WEAPONS 27
|
||||||
|
|
||||||
|
.float boxstatus;
|
||||||
.entity boxweapon;
|
.entity boxweapon;
|
||||||
.float spins;
|
.float spins;
|
||||||
.float papState;
|
.float papState;
|
||||||
float BoxWeapons[27];
|
|
||||||
float mystery_box_count;
|
var struct mbox_struct
|
||||||
entity mystery_boxes[16];
|
{
|
||||||
vector boxOrigin;
|
float weapon_id; // ID for the relevant weapon.
|
||||||
|
float allowed; // 1 for allowed, 0 for denied.
|
||||||
|
float rarity; // 0-100 (float) percent change for obtaining. -1 for normal.
|
||||||
|
} mystery_box_weapons[MAX_BOX_WEAPONS] = {};
|
||||||
|
|
||||||
|
float mystery_box_count;
|
||||||
|
float mystery_box_leave_count;
|
||||||
|
float mystery_box_cost;
|
||||||
|
string mystery_box_model;
|
||||||
|
string mystery_box_glow_model;
|
||||||
|
string mystery_box_open_sound;
|
||||||
|
string mystery_box_close_sound;
|
||||||
|
entity mystery_boxes[16];
|
||||||
|
vector mystery_box_start_origin;
|
||||||
|
|
||||||
#ifdef FTE
|
#ifdef FTE
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,6 @@ void() light_flame_small_white = // Light with small flame & fire sound
|
||||||
//
|
//
|
||||||
void(entity e) Light_Red =
|
void(entity e) Light_Red =
|
||||||
{
|
{
|
||||||
e.effects = e.effects | EF_FULLBRIGHT;
|
|
||||||
|
|
||||||
#ifndef FTE
|
#ifndef FTE
|
||||||
|
|
||||||
|
@ -135,7 +134,6 @@ void(entity e) Light_Red =
|
||||||
//
|
//
|
||||||
void(entity e) Light_Green =
|
void(entity e) Light_Green =
|
||||||
{
|
{
|
||||||
e.effects = e.effects | EF_FULLBRIGHT;
|
|
||||||
|
|
||||||
#ifndef FTE
|
#ifndef FTE
|
||||||
|
|
||||||
|
@ -161,7 +159,6 @@ void(entity e) Light_Green =
|
||||||
//
|
//
|
||||||
void(entity e) Light_Blue =
|
void(entity e) Light_Blue =
|
||||||
{
|
{
|
||||||
e.effects = e.effects | EF_FULLBRIGHT;
|
|
||||||
|
|
||||||
#ifndef FTE
|
#ifndef FTE
|
||||||
|
|
||||||
|
@ -187,7 +184,6 @@ void(entity e) Light_Blue =
|
||||||
//
|
//
|
||||||
void(entity e) Light_Orange =
|
void(entity e) Light_Orange =
|
||||||
{
|
{
|
||||||
e.effects = e.effects | EF_FULLBRIGHT;
|
|
||||||
|
|
||||||
#ifndef FTE
|
#ifndef FTE
|
||||||
|
|
||||||
|
@ -213,7 +209,6 @@ void(entity e) Light_Orange =
|
||||||
//
|
//
|
||||||
void(entity e) Light_Purple =
|
void(entity e) Light_Purple =
|
||||||
{
|
{
|
||||||
e.effects = e.effects | EF_FULLBRIGHT;
|
|
||||||
|
|
||||||
#ifndef FTE
|
#ifndef FTE
|
||||||
|
|
||||||
|
@ -239,7 +234,6 @@ void(entity e) Light_Purple =
|
||||||
//
|
//
|
||||||
void(entity e) Light_Cyan =
|
void(entity e) Light_Cyan =
|
||||||
{
|
{
|
||||||
e.effects = e.effects | EF_FULLBRIGHT;
|
|
||||||
|
|
||||||
#ifndef FTE
|
#ifndef FTE
|
||||||
|
|
||||||
|
@ -265,7 +259,6 @@ void(entity e) Light_Cyan =
|
||||||
//
|
//
|
||||||
void(entity e) Light_Pink =
|
void(entity e) Light_Pink =
|
||||||
{
|
{
|
||||||
e.effects = e.effects | EF_FULLBRIGHT;
|
|
||||||
|
|
||||||
#ifndef FTE
|
#ifndef FTE
|
||||||
|
|
||||||
|
@ -291,7 +284,6 @@ void(entity e) Light_Pink =
|
||||||
//
|
//
|
||||||
void(entity e) Light_Lime =
|
void(entity e) Light_Lime =
|
||||||
{
|
{
|
||||||
e.effects = e.effects | EF_FULLBRIGHT;
|
|
||||||
|
|
||||||
#ifndef FTE
|
#ifndef FTE
|
||||||
|
|
||||||
|
@ -317,7 +309,6 @@ void(entity e) Light_Lime =
|
||||||
//
|
//
|
||||||
void(entity e) Light_Yellow =
|
void(entity e) Light_Yellow =
|
||||||
{
|
{
|
||||||
e.effects = e.effects | EF_FULLBRIGHT;
|
|
||||||
|
|
||||||
#ifndef FTE
|
#ifndef FTE
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ float backupWepSkin;
|
||||||
float sound_perk_delay;
|
float sound_perk_delay;
|
||||||
void() W_Switch;
|
void() W_Switch;
|
||||||
void() W_TakeOut;
|
void() W_TakeOut;
|
||||||
void() mystery_touch;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// --------------------
|
// --------------------
|
||||||
|
|
|
@ -26,10 +26,55 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void(vector where, float time_alive) SpawnSpark;
|
void(vector where, float time_alive) SpawnSpark;
|
||||||
|
void() MBOX_Touch;
|
||||||
|
|
||||||
#define MBOX_SPAWNFLAG_NOTHERE 1
|
#define MBOX_SPAWNFLAG_NOTHERE 1
|
||||||
#define MBOX_SPAWNFLAG_NOLIGHT 2
|
#define MBOX_SPAWNFLAG_NOLIGHT 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// MBOX_UpdateGlowFrame()
|
||||||
|
// Updates the Glow model frame to match
|
||||||
|
// the box if it exists.
|
||||||
|
//
|
||||||
|
void() MBOX_UpdateGlowFrame =
|
||||||
|
{
|
||||||
|
if (self.goaldummy) self.goaldummy.frame = self.frame;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// MBOX_PlayOpenAnimation()
|
||||||
|
// Plays the open animation for the Mystery Box,
|
||||||
|
// frames 1-8.
|
||||||
|
//
|
||||||
|
void() MBOX_PlayOpenAnimation = [1, MBOX_OpenAnimation2 ] { self.frame = 1; MBOX_UpdateGlowFrame(); Light_Yellow(self); };
|
||||||
|
void() MBOX_OpenAnimation2 = [2, MBOX_OpenAnimation3 ] { self.frame = 2; MBOX_UpdateGlowFrame(); };
|
||||||
|
void() MBOX_OpenAnimation3 = [3, MBOX_OpenAnimation4 ] { self.frame = 3; MBOX_UpdateGlowFrame(); };
|
||||||
|
void() MBOX_OpenAnimation4 = [4, MBOX_OpenAnimation5 ] { self.frame = 4; MBOX_UpdateGlowFrame(); };
|
||||||
|
void() MBOX_OpenAnimation5 = [5, MBOX_OpenAnimation6 ] { self.frame = 5; MBOX_UpdateGlowFrame(); };
|
||||||
|
void() MBOX_OpenAnimation6 = [6, MBOX_OpenAnimation7 ] { self.frame = 6; MBOX_UpdateGlowFrame(); };
|
||||||
|
void() MBOX_OpenAnimation7 = [7, MBOX_OpenAnimation8 ] { self.frame = 7; MBOX_UpdateGlowFrame(); };
|
||||||
|
void() MBOX_OpenAnimation8 = [8, SUB_Null ] { self.frame = 8; MBOX_UpdateGlowFrame(); };
|
||||||
|
|
||||||
|
//
|
||||||
|
// MBOX_Reset()
|
||||||
|
// Resets the Mystery Box to be ready for
|
||||||
|
// another use.
|
||||||
|
//
|
||||||
|
inline void() MBOX_Reset =
|
||||||
|
{
|
||||||
|
self.frame = 0;
|
||||||
|
self.boxstatus = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// MBOX_PlayCloseAnimation()
|
||||||
|
// Plays the open animation for the Mystery Box,
|
||||||
|
// frames 9-12.
|
||||||
|
//
|
||||||
|
void() MBOX_PlayCloseAnimation = [9, MBOX_CloseAnimation2 ] { self.frame = 9; MBOX_UpdateGlowFrame(); sound (self, CHAN_ITEM, mystery_box_close_sound, 1, ATTN_NORM); Light_None(self); };
|
||||||
|
void() MBOX_CloseAnimation2 = [10, MBOX_CloseAnimation3 ] { self.frame = 10; MBOX_UpdateGlowFrame(); };
|
||||||
|
void() MBOX_CloseAnimation3 = [10, MBOX_CloseAnimation4 ] { self.frame = 11; MBOX_UpdateGlowFrame(); };
|
||||||
|
void() MBOX_CloseAnimation4 = [10, MBOX_Reset ] { self.frame = 12; MBOX_UpdateGlowFrame(); };
|
||||||
|
|
||||||
//
|
//
|
||||||
// MBOX_FreeEnt(ent)
|
// MBOX_FreeEnt(ent)
|
||||||
|
@ -66,137 +111,21 @@ entity() MBOX_GetFreeEnt =
|
||||||
return ent;
|
return ent;
|
||||||
};
|
};
|
||||||
|
|
||||||
void() updateBoxGlow
|
//
|
||||||
|
// MBOX_GetRandomBoxWeapon(user)
|
||||||
|
// Returns a weapon from the Mystery Box allow-list
|
||||||
|
// that the user is not holding.
|
||||||
|
//
|
||||||
|
float(entity user) MBOX_GetRandomBoxWeapon =
|
||||||
{
|
{
|
||||||
if(self.goaldummy)
|
float weapon_index = rint((random() * (MAX_BOX_WEAPONS - 1)));
|
||||||
{
|
float weapon_id = mystery_box_weapons[weapon_index].weapon_id;
|
||||||
self.goaldummy.frame = self.frame;
|
float weapon_allowed = mystery_box_weapons[weapon_index].allowed;
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
if (weapon_allowed == true && !Weapon_PlayerHasWeapon(user, weapon_id, true))
|
||||||
void() box_open1 =[ 1, box_open2 ] { self.frame = 1;updateBoxGlow(); Light_Yellow(self);};
|
return weapon_id;
|
||||||
void() box_open2 =[ 2, box_open3 ] { self.frame = 2;updateBoxGlow();};
|
else
|
||||||
void() box_open3 =[ 3, box_open4 ] { self.frame = 3;updateBoxGlow();};
|
return MBOX_GetRandomBoxWeapon(user);
|
||||||
void() box_open4 =[ 4, box_open5 ] { self.frame = 4;updateBoxGlow();};
|
|
||||||
void() box_open5 =[ 5, box_open6 ] { self.frame = 5;updateBoxGlow();};
|
|
||||||
void() box_open6 =[ 6, box_open7 ] { self.frame = 6;updateBoxGlow();};
|
|
||||||
void() box_open7 =[ 7, box_open8 ] { self.frame = 7;updateBoxGlow();};
|
|
||||||
void() box_open8 =[ 8, SUB_Null ] { self.frame = 8;updateBoxGlow();};
|
|
||||||
|
|
||||||
void() resetbox =
|
|
||||||
{
|
|
||||||
self.frame = 0;
|
|
||||||
self.boxstatus = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void() box_close1 =[ 9, box_close2 ] { self.frame = 9;updateBoxGlow();sound (self, CHAN_ITEM, "sounds/machines/mbox_close.wav", 1, ATTN_NORM); Light_None(self);};
|
|
||||||
void() box_close2 =[ 10, box_close3 ] { self.frame = 10;updateBoxGlow();};
|
|
||||||
void() box_close3 =[ 11, box_close4 ] { self.frame = 11;updateBoxGlow();};
|
|
||||||
void() box_close4 =[ 12, resetbox ] { self.frame = 12;updateBoxGlow();};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Getweaponid()
|
|
||||||
// Returns weapon ID from Mbox ID, as they are slightly different
|
|
||||||
// because.. reasons..
|
|
||||||
//
|
|
||||||
float(float r) Getweaponid =
|
|
||||||
{
|
|
||||||
switch(r) {
|
|
||||||
case 0:
|
|
||||||
return W_COLT;
|
|
||||||
case 1:
|
|
||||||
return W_KAR;
|
|
||||||
case 2:
|
|
||||||
return W_DB;
|
|
||||||
case 3:
|
|
||||||
return W_MG;
|
|
||||||
case 4:
|
|
||||||
return W_RAY;
|
|
||||||
case 5:
|
|
||||||
return W_THOMPSON;
|
|
||||||
case 6:
|
|
||||||
return W_M2;
|
|
||||||
case 7:
|
|
||||||
return W_PPSH;
|
|
||||||
case 8:
|
|
||||||
return W_SAWNOFF;
|
|
||||||
case 9:
|
|
||||||
return W_TESLA;
|
|
||||||
case 10:
|
|
||||||
return W_M1A1;
|
|
||||||
case 11:
|
|
||||||
return W_GEWEHR;
|
|
||||||
case 12:
|
|
||||||
return W_FG;
|
|
||||||
case 13:
|
|
||||||
return W_BROWNING;
|
|
||||||
case 14:
|
|
||||||
return W_KAR_SCOPE;
|
|
||||||
case 15:
|
|
||||||
return W_357;
|
|
||||||
case 16:
|
|
||||||
return W_STG;
|
|
||||||
case 17:
|
|
||||||
return W_PANZER;
|
|
||||||
case 18:
|
|
||||||
return W_BK;
|
|
||||||
case 19:
|
|
||||||
return W_PTRS;
|
|
||||||
case 20:
|
|
||||||
return W_MP40;
|
|
||||||
case 21:
|
|
||||||
return W_TRENCH;
|
|
||||||
case 22:
|
|
||||||
return W_BAR;
|
|
||||||
case 23:
|
|
||||||
return W_M1;
|
|
||||||
case 24:
|
|
||||||
return W_TYPE;
|
|
||||||
case 25:
|
|
||||||
return W_MP5K;
|
|
||||||
case 26:
|
|
||||||
return W_SPRING;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// randomweapon()
|
|
||||||
// Returns a Weapon if permitted by the map's MBOX data file.
|
|
||||||
//
|
|
||||||
float() randomweapon =
|
|
||||||
{
|
|
||||||
float r;
|
|
||||||
r = rint((random() * 26));
|
|
||||||
|
|
||||||
// If this weapon is in our Box Array, we can return it.
|
|
||||||
if (BoxWeapons[r] == 1) {
|
|
||||||
return r;
|
|
||||||
} else { // It's not in the Array, try again until we find one.
|
|
||||||
return randomweapon();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// CheckWeapon(w, user)
|
|
||||||
// Checks all 3 weapon slots to see if the Player is holding specified
|
|
||||||
// Weapon, ensures we do not give Duplicates.
|
|
||||||
//
|
|
||||||
float CheckWeapon (float w, entity user) =
|
|
||||||
{
|
|
||||||
// Non-PaP Weapons
|
|
||||||
if (user.weapon == w || user.secondaryweapon == w || user.thirdweapon == w)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// PaP Weapons
|
|
||||||
if (EqualNonPapWeapon(user.weapon) == w || EqualNonPapWeapon(user.secondaryweapon) == w || EqualNonPapWeapon(user.thirdweapon) == w)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// We passed both, this weapon is okay
|
|
||||||
return 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -209,7 +138,7 @@ void() Reset_MBox =
|
||||||
self.velocity = '0 0 0';
|
self.velocity = '0 0 0';
|
||||||
tempe = self;
|
tempe = self;
|
||||||
self = self.owner;
|
self = self.owner;
|
||||||
box_close1();
|
MBOX_PlayCloseAnimation();
|
||||||
self = tempe;
|
self = tempe;
|
||||||
self.owner.owner = world;
|
self.owner.owner = world;
|
||||||
self.owner.boxstatus = 0;
|
self.owner.boxstatus = 0;
|
||||||
|
@ -264,7 +193,7 @@ void() findboxspot =
|
||||||
g = MBOX_GetFreeEnt();
|
g = MBOX_GetFreeEnt();
|
||||||
g.classname = "mystery_glow";
|
g.classname = "mystery_glow";
|
||||||
newspot.goaldummy = g;
|
newspot.goaldummy = g;
|
||||||
setmodel(g,"models/machines/mglow$.mdl");
|
setmodel(g, mystery_box_glow_model);
|
||||||
setorigin(g,newspot.origin);
|
setorigin(g,newspot.origin);
|
||||||
g.angles = newspot.angles;
|
g.angles = newspot.angles;
|
||||||
|
|
||||||
|
@ -282,23 +211,23 @@ void() findboxspot =
|
||||||
// Set some values and change the found Spot to an MBox
|
// Set some values and change the found Spot to an MBox
|
||||||
newspot.spins = 0;
|
newspot.spins = 0;
|
||||||
newspot.boxstatus = 0;
|
newspot.boxstatus = 0;
|
||||||
newspot.touch = mystery_touch;
|
newspot.touch = MBOX_Touch;
|
||||||
newspot.solid=SOLID_TRIGGER;
|
newspot.solid=SOLID_TRIGGER;
|
||||||
newspot.classname = "mystery";
|
newspot.classname = "mystery";
|
||||||
newspot.spawnflags = self.owner.spawnflags;
|
newspot.spawnflags = self.owner.spawnflags;
|
||||||
setorigin(newspot, newspot.origin);
|
setorigin(newspot, newspot.origin);
|
||||||
setmodel (newspot, "models/machines/mystery.mdl");
|
setmodel (newspot, mystery_box_model);
|
||||||
newspot.frame = 0;
|
newspot.frame = 0;
|
||||||
setsize (newspot, VEC_HULL2_MIN, VEC_HULL2_MAX);
|
setsize (newspot, VEC_HULL2_MIN, VEC_HULL2_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// MBOX_MakeActive()
|
// MBOX_MakeActive()
|
||||||
// Sets the Mystery Box touch to mystery_touch (delay)
|
// Sets the Mystery Box touch to MBOX_Touch (delay)
|
||||||
//
|
//
|
||||||
void() MBOX_MakeActive =
|
void() MBOX_MakeActive =
|
||||||
{
|
{
|
||||||
self.touch = mystery_touch;
|
self.touch = MBOX_Touch;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -326,7 +255,7 @@ void() MBOX_FindNewSpot =
|
||||||
new_box.solid = SOLID_TRIGGER;
|
new_box.solid = SOLID_TRIGGER;
|
||||||
new_box.classname = "mystery";
|
new_box.classname = "mystery";
|
||||||
new_box.frame = 0;
|
new_box.frame = 0;
|
||||||
setmodel(new_box, "models/machines/mystery.mdl");
|
setmodel(new_box, mystery_box_model);
|
||||||
setsize(new_box, VEC_HULL2_MIN, VEC_HULL2_MAX);
|
setsize(new_box, VEC_HULL2_MIN, VEC_HULL2_MAX);
|
||||||
|
|
||||||
// Spawn the Box Glow if permitted
|
// Spawn the Box Glow if permitted
|
||||||
|
@ -336,7 +265,7 @@ void() MBOX_FindNewSpot =
|
||||||
light = MBOX_GetFreeEnt();
|
light = MBOX_GetFreeEnt();
|
||||||
light.classname = "mystery_glow";
|
light.classname = "mystery_glow";
|
||||||
new_box.goaldummy = light;
|
new_box.goaldummy = light;
|
||||||
setmodel(light,"models/machines/mglow$.mdl");
|
setmodel(light, mystery_box_glow_model);
|
||||||
setorigin(light, new_box.origin);
|
setorigin(light, new_box.origin);
|
||||||
light.angles = new_box.angles;
|
light.angles = new_box.angles;
|
||||||
light.effects = EF_FULLBRIGHT;
|
light.effects = EF_FULLBRIGHT;
|
||||||
|
@ -481,7 +410,7 @@ void() MBOX_TeddyLeave =
|
||||||
void() MBOX_PresentTeddy =
|
void() MBOX_PresentTeddy =
|
||||||
{
|
{
|
||||||
// Return the Player's points.
|
// Return the Player's points.
|
||||||
addmoney(self.owner.owner, 950, 0);
|
addmoney(self.owner.owner, mystery_box_cost, 0);
|
||||||
// Broadcast the bad luck.
|
// Broadcast the bad luck.
|
||||||
sound(self, CHAN_ITEM, "sounds/misc/buy.wav", 1, ATTN_NONE);
|
sound(self, CHAN_ITEM, "sounds/misc/buy.wav", 1, ATTN_NONE);
|
||||||
sound(self, 2, "sounds/misc/giggle.wav", 1, ATTN_NONE);
|
sound(self, 2, "sounds/misc/giggle.wav", 1, ATTN_NONE);
|
||||||
|
@ -490,54 +419,79 @@ void() MBOX_PresentTeddy =
|
||||||
self.nextthink = time + 2;
|
self.nextthink = time + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// MBOX_GetLeaveChancePercentage()
|
||||||
|
// Generates a percentage chance for the Mystery Box
|
||||||
|
// to leave.
|
||||||
|
//
|
||||||
|
float(float uses) MBOX_GetLeaveChancePercentage =
|
||||||
|
{
|
||||||
|
// If there's only one Mystery Box, never try to leave.
|
||||||
|
// Additionally, you're always given 4 free uses.
|
||||||
|
if (mystery_box_count == 1 || uses <= 4)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
float chance_to_leave = 0;
|
||||||
|
|
||||||
|
// There is a hardcoded 100% chance to leave after 8 uses
|
||||||
|
// if the box hasn't moved yet in a game.
|
||||||
|
if (mystery_box_leave_count == 0 && uses >= 8)
|
||||||
|
chance_to_leave = 100;
|
||||||
|
|
||||||
|
// There's a 15% chance for leaving if this is between the uses
|
||||||
|
// of 4 and 8.
|
||||||
|
if (uses >= 4 && uses < 8)
|
||||||
|
chance_to_leave = 15;
|
||||||
|
|
||||||
|
// Mystery Box behavior changes after it leaves for the first time
|
||||||
|
if (mystery_box_leave_count > 0) {
|
||||||
|
// 30% chance of leaving between uses 8 and 12.
|
||||||
|
if (uses >= 8 && uses < 12)
|
||||||
|
chance_to_leave = 30;
|
||||||
|
// 50% chance after the 12th use.
|
||||||
|
else if (uses >= 12)
|
||||||
|
chance_to_leave = 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chance_to_leave/100;
|
||||||
|
}
|
||||||
|
|
||||||
void() Float_Change =
|
void() Float_Change =
|
||||||
{
|
{
|
||||||
entity tpspot;
|
float tempf;
|
||||||
float r, tempf, teddygen;
|
|
||||||
string temps;
|
string temps;
|
||||||
|
|
||||||
tempf = randomweapon();
|
float leave_chance;
|
||||||
r = Getweaponid(tempf);
|
|
||||||
while (!CheckWeapon (r, self.owner.owner))
|
tempf = MBOX_GetRandomBoxWeapon(self.owner.owner);
|
||||||
{
|
temps = GetWeaponModel(tempf, 1);
|
||||||
tempf = randomweapon();
|
|
||||||
r = Getweaponid(tempf);
|
|
||||||
}
|
|
||||||
temps = GetWeaponModel(r, 1);
|
|
||||||
setmodel (self, temps);
|
setmodel (self, temps);
|
||||||
|
|
||||||
self.boxstatus = self.boxstatus + 0.01;
|
self.boxstatus = self.boxstatus + 0.01;
|
||||||
if (self.wait <= time)
|
if (self.wait <= time)
|
||||||
{
|
{
|
||||||
tpspot = find(world, classname, "mystery_box_tp_spot");
|
leave_chance = MBOX_GetLeaveChancePercentage(self.owner.spins);
|
||||||
if (tpspot != world && self.owner.spins > 3) {
|
|
||||||
teddygen = random();
|
|
||||||
//bprint(PRINT_HIGH, "found tp spot\n");
|
|
||||||
} else {
|
|
||||||
teddygen = 0;
|
|
||||||
//bprint(PRINT_HIGH, "no tp spot or spins < 3\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
self.velocity = '0 0 0';
|
self.velocity = '0 0 0';
|
||||||
|
|
||||||
if (!teddygen || teddygen < 0.7) { //teddy gen threshold, high means less chance
|
if (random() > leave_chance) { //teddy gen threshold, high means less chance
|
||||||
self.owner.boxstatus = 2;
|
self.owner.boxstatus = 2;
|
||||||
self.weapon = r;
|
self.weapon = tempf;
|
||||||
self.nextthink = time + 5;
|
self.nextthink = time + 5;
|
||||||
self.think = Float_Decrease;
|
self.think = Float_Decrease;
|
||||||
//bprint(PRINT_HIGH, "spot not found, or teddygun is > 0.7\n");
|
//bprint(PRINT_HIGH, "spot not found, or teddygun is > 0.7\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
addmoney(self.owner.owner, 950, 0);
|
addmoney(self.owner.owner, mystery_box_cost, 0);
|
||||||
self.model = "models/props/teddy.mdl";
|
self.model = "models/props/teddy.mdl";
|
||||||
setmodel(self, self.model);
|
setmodel(self, self.model);
|
||||||
self.angles_y = self.angles_y - 90;
|
self.angles_y = self.angles_y - 90;
|
||||||
self.nextthink = time + 1;
|
self.nextthink = time + 1;
|
||||||
self.think = MBOX_PresentTeddy;
|
self.think = MBOX_PresentTeddy;
|
||||||
ach_tracker_luck++;
|
mystery_box_leave_count++;
|
||||||
|
|
||||||
if (ach_tracker_luck >= 10)
|
if (mystery_box_leave_count >= 10)
|
||||||
GiveAchievement(11);
|
GiveAchievement(11);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -566,7 +520,7 @@ void() finish_mbox_setup =
|
||||||
g.classname = "mystery_glow";
|
g.classname = "mystery_glow";
|
||||||
|
|
||||||
self.goaldummy = g;
|
self.goaldummy = g;
|
||||||
setmodel(g,"models/machines/mglow$.mdl");
|
setmodel(g, mystery_box_glow_model);
|
||||||
setorigin(g,self.origin);
|
setorigin(g,self.origin);
|
||||||
g.angles = self.angles;
|
g.angles = self.angles;
|
||||||
|
|
||||||
|
@ -579,34 +533,32 @@ void() finish_mbox_setup =
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void() allocate_floating_weapons =
|
//
|
||||||
|
// MBOX_AllocateTempEntities()
|
||||||
|
// Spawns in all of the temp entities that are
|
||||||
|
// used for the floating weapons, teddy bear,
|
||||||
|
// and glow.
|
||||||
|
//
|
||||||
|
void() MBOX_AllocateTempEntities =
|
||||||
{
|
{
|
||||||
self.think = SUB_Null;
|
self.think = SUB_Null;
|
||||||
|
|
||||||
// Spawn all of our floating weapon entities
|
|
||||||
// Multiply by 2 to account for the glow.
|
|
||||||
for (float i = 0; i < mystery_box_count * 3; i++) {
|
for (float i = 0; i < mystery_box_count * 3; i++) {
|
||||||
entity tempe = spawn();
|
entity tempe = spawn();
|
||||||
tempe.classname = "freeMboxEntity";
|
tempe.classname = "freeMboxEntity";
|
||||||
}
|
}
|
||||||
|
|
||||||
finish_mbox_setup();
|
finish_mbox_setup();
|
||||||
}
|
};
|
||||||
|
|
||||||
void() Create_Floating_Weapon =
|
void() Create_Floating_Weapon =
|
||||||
{
|
{
|
||||||
entity gun;
|
entity gun;
|
||||||
float r, tempf;
|
float tempf;
|
||||||
string temps;
|
string temps;
|
||||||
|
|
||||||
tempf = randomweapon();
|
tempf = MBOX_GetRandomBoxWeapon(self.owner.owner);
|
||||||
r = Getweaponid(tempf);
|
temps = GetWeaponModel(tempf, 1);
|
||||||
while (!CheckWeapon (r, self.owner.owner))
|
|
||||||
{
|
|
||||||
tempf = randomweapon();
|
|
||||||
r = Getweaponid(tempf);
|
|
||||||
}
|
|
||||||
temps = GetWeaponModel(r, 1);
|
|
||||||
|
|
||||||
gun = MBOX_GetFreeEnt();
|
gun = MBOX_GetFreeEnt();
|
||||||
gun.classname = "mystery_weapon";
|
gun.classname = "mystery_weapon";
|
||||||
|
@ -615,7 +567,6 @@ void() Create_Floating_Weapon =
|
||||||
setmodel (gun, temps);
|
setmodel (gun, temps);
|
||||||
setsize (gun, '0 0 0', '0 0 0');
|
setsize (gun, '0 0 0', '0 0 0');
|
||||||
gun.angles = self.angles;
|
gun.angles = self.angles;
|
||||||
gun.effects = EF_FULLBRIGHT;
|
|
||||||
|
|
||||||
gun.movetype = MOVETYPE_NOCLIP;
|
gun.movetype = MOVETYPE_NOCLIP;
|
||||||
gun.solid = SOLID_NOT;
|
gun.solid = SOLID_NOT;
|
||||||
|
@ -653,7 +604,7 @@ void() mystery_box_tp_spot =
|
||||||
mystery_box_count++;
|
mystery_box_count++;
|
||||||
};
|
};
|
||||||
|
|
||||||
void() mystery_touch =
|
void() MBOX_Touch =
|
||||||
{
|
{
|
||||||
entity tempe;
|
entity tempe;
|
||||||
|
|
||||||
|
@ -661,10 +612,17 @@ void() mystery_touch =
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!self.boxstatus) {
|
if (!self.boxstatus) {
|
||||||
useprint (other, 6, 950, 0);
|
useprint (other, 6, mystery_box_cost, 0);
|
||||||
}
|
}
|
||||||
if (self.boxstatus == 2 && self.owner == other) {
|
if (self.boxstatus == 2 && self.owner == other) {
|
||||||
useprint (other, 7, 0, 0);
|
|
||||||
|
#ifndef FTE
|
||||||
|
|
||||||
|
other.Weapon_Name_Touch = GetWeaponName(self.boxweapon.weapon);
|
||||||
|
|
||||||
|
#endif // FTE
|
||||||
|
|
||||||
|
useprint (other, 7, 0, self.boxweapon.weapon);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (other.button7 && !other.semiuse)
|
if (other.button7 && !other.semiuse)
|
||||||
|
@ -672,13 +630,13 @@ void() mystery_touch =
|
||||||
other.semiuse = true;
|
other.semiuse = true;
|
||||||
if (!self.boxstatus)
|
if (!self.boxstatus)
|
||||||
{
|
{
|
||||||
if (other.points >= 950)
|
if (other.points >= mystery_box_cost)
|
||||||
{
|
{
|
||||||
sound (self, CHAN_ITEM, "sounds/machines/mbox_open.wav", 1, ATTN_NORM);
|
sound (self, CHAN_ITEM, mystery_box_open_sound, 1, ATTN_NORM);
|
||||||
addmoney(other, -950, FALSE);
|
addmoney(other, -mystery_box_cost, FALSE);
|
||||||
self.boxstatus = 1;
|
self.boxstatus = 1;
|
||||||
self.owner = other;
|
self.owner = other;
|
||||||
box_open1 ();
|
MBOX_PlayOpenAnimation();
|
||||||
Create_Floating_Weapon();
|
Create_Floating_Weapon();
|
||||||
self.spins++;
|
self.spins++;
|
||||||
}
|
}
|
||||||
|
@ -781,91 +739,314 @@ void() mystery_touch =
|
||||||
SwitchWeapon(self.weapon);
|
SwitchWeapon(self.weapon);
|
||||||
self = tempe;
|
self = tempe;
|
||||||
MBOX_FreeEnt(self.boxweapon);
|
MBOX_FreeEnt(self.boxweapon);
|
||||||
box_close1();
|
MBOX_PlayCloseAnimation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Load_Mbox_Data()
|
// MBOX_GetWeaponIDFromMB1(mbox_id)
|
||||||
// Opens the map's MBOX Data File and adds parsed data
|
// .mbox weapon IDs did not 100% correlate
|
||||||
// into the Box's weapon Array.
|
// to internal weapon IDs, so this converts
|
||||||
// ----------
|
// them appropriately.
|
||||||
// TODO: Possibly investigate making this a little better and more modular
|
|
||||||
// so adding MBOX Weapons can be easier?
|
|
||||||
//
|
//
|
||||||
void() Load_Mbox_Data =
|
float MBOX_GetWeaponIDFromMB1(float mbox_id) =
|
||||||
{
|
{
|
||||||
float file;
|
switch(mbox_id) {
|
||||||
string h;
|
case 0: return W_COLT;
|
||||||
int weapons_all_disabled = 1;
|
case 1: return W_KAR;
|
||||||
|
case 2: return W_DB;
|
||||||
|
case 3: return W_MG;
|
||||||
|
case 4: return W_RAY;
|
||||||
|
case 5: return W_THOMPSON;
|
||||||
|
case 6: return W_M2;
|
||||||
|
case 7: return W_PPSH;
|
||||||
|
case 8: return W_SAWNOFF;
|
||||||
|
case 9: return W_TESLA;
|
||||||
|
case 10: return W_M1A1;
|
||||||
|
case 11: return W_GEWEHR;
|
||||||
|
case 12: return W_FG;
|
||||||
|
case 13: return W_BROWNING;
|
||||||
|
case 14: return W_KAR_SCOPE;
|
||||||
|
case 15: return W_357;
|
||||||
|
case 16: return W_STG;
|
||||||
|
case 17: return W_PANZER;
|
||||||
|
case 18: return W_BK;
|
||||||
|
case 19: return W_PTRS;
|
||||||
|
case 20: return W_MP40;
|
||||||
|
case 21: return W_TRENCH;
|
||||||
|
case 22: return W_BAR;
|
||||||
|
case 23: return W_M1;
|
||||||
|
case 24: return W_TYPE;
|
||||||
|
case 25: return W_MP5K;
|
||||||
|
case 26: return W_SPRING;
|
||||||
|
default: return W_COLT;
|
||||||
|
}
|
||||||
|
return W_COLT;
|
||||||
|
}
|
||||||
|
|
||||||
// Attempt to Open the File
|
//
|
||||||
h = strcat(mapname, ".mbox");
|
// MBOX_PrecacheWeaponData()
|
||||||
h = strcat("maps/", h);
|
// Iterates through the weapon array and
|
||||||
file = fopen (h, FILE_READ);
|
// allocates necessary content for each
|
||||||
|
// allowed weapon.
|
||||||
|
//
|
||||||
|
void() MBOX_PrecacheWeaponContent =
|
||||||
|
{
|
||||||
|
for (float i = 0; i < MAX_BOX_WEAPONS; i++) {
|
||||||
|
if (mystery_box_weapons[i].allowed == true) {
|
||||||
|
precache_model(GetWeaponModel(mystery_box_weapons[i].weapon_id, 0));
|
||||||
|
precache_model(GetWeaponModel(mystery_box_weapons[i].weapon_id, 1));
|
||||||
|
precache_extra(mystery_box_weapons[i].weapon_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// There was no MBOX Data, enable all Weapons!
|
//
|
||||||
// R.I.P. PSP Memory 90% of the time in this case..
|
// MBOX_ParseMB1File(mbox_file)
|
||||||
if (file == -1) {
|
// Parses the old (2014) .mbox file and loads
|
||||||
for (float i = 0; i < 27; i++) {
|
// it into the necessary structure.
|
||||||
BoxWeapons[i] = 1;
|
//
|
||||||
}
|
void(float mbox_file) MBOX_ParseMB1File =
|
||||||
fclose(file);
|
{
|
||||||
} else {
|
string file_line;
|
||||||
// Parse each Line and write the Data into our Array.
|
|
||||||
for (float i = 0; i < 27; i++) {
|
|
||||||
h = strtrim((fgets(file)));
|
|
||||||
BoxWeapons[i] = stof(h);
|
|
||||||
|
|
||||||
if (stof(h) == 1)
|
|
||||||
weapons_all_disabled = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (weapons_all_disabled) {
|
|
||||||
for (float i = 0; i < 27; i++) {
|
|
||||||
BoxWeapons[i] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(float i = 0; i < 27; i++) {
|
// Parse the .mbox line-by-line and fill the data structure.
|
||||||
// Precache Weapon Data if enabled
|
for (float i = 0; i < MAX_BOX_WEAPONS; i++) {
|
||||||
if (BoxWeapons[i]) {
|
file_line = strtrim((fgets(mbox_file)));
|
||||||
precache_model(GetWeaponModel(Getweaponid(i), 0));
|
mystery_box_weapons[i].weapon_id = MBOX_GetWeaponIDFromMB1(i);
|
||||||
precache_model(GetWeaponModel(Getweaponid(i), 1));
|
mystery_box_weapons[i].allowed = stof(file_line);
|
||||||
precache_extra(Getweaponid(i));
|
mystery_box_weapons[i].rarity = -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fclose(file);
|
// Precache the allowed weapons
|
||||||
|
MBOX_PrecacheWeaponContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// MBOX_GetUnusedWeaponID()
|
||||||
|
// Returns a weapon ID for a potential
|
||||||
|
// box weapon that is not currently
|
||||||
|
// in the list.
|
||||||
|
//
|
||||||
|
float() MBOX_GetUnusedWeaponID =
|
||||||
|
{
|
||||||
|
// Iterate over every potential Box Weapon
|
||||||
|
for (float i = 0; i < MAX_BOX_WEAPONS; i++) {
|
||||||
|
float weapon_in_use = false;
|
||||||
|
float weapon_id = MBOX_GetWeaponIDFromMB1(i);
|
||||||
|
|
||||||
|
// Now over every weapon in the list
|
||||||
|
for (float j = 0; j < MAX_BOX_WEAPONS; j++) {
|
||||||
|
if (mystery_box_weapons[j].weapon_id == weapon_id)
|
||||||
|
weapon_in_use = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weapon_in_use == false) {
|
||||||
|
return weapon_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error("MBOX_GetunusedWeaponID: Could not find a free weapon slot!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// MBOX_ParseMB2File(mbox_file)
|
||||||
|
// Parses the current .mb2 file and loads it
|
||||||
|
// into the necessary structure.
|
||||||
|
//
|
||||||
|
void(float mbox_file) MBOX_ParseMB2File =
|
||||||
|
{
|
||||||
|
string file_line;
|
||||||
|
|
||||||
|
// Read the first line: It's our "header", should be
|
||||||
|
// "nzp_mbox2".
|
||||||
|
file_line = strtrim((fgets(mbox_file)));
|
||||||
|
|
||||||
|
if (file_line != "nzp_mbox2")
|
||||||
|
error(strcat("MBOX_ParseMB2File: Expected \"nzp_mbox2\" but got ", file_line));
|
||||||
|
|
||||||
|
// Read each line of the file in a loop
|
||||||
|
float finished_parsing = false;
|
||||||
|
float parsing_state = 0;
|
||||||
|
float is_allow_not_deny = false;
|
||||||
|
float weapons_parsed = 0;
|
||||||
|
float weapon_id = 0;
|
||||||
|
while(!finished_parsing) {
|
||||||
|
// Grab a new line
|
||||||
|
file_line = fgets(mbox_file);
|
||||||
|
|
||||||
|
// End of file.
|
||||||
|
if not (file_line) {
|
||||||
|
finished_parsing = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_line = strzone(strtrim(file_line));
|
||||||
|
|
||||||
|
// Check for comments, they always start with '#'.
|
||||||
|
// Also ignore whitespace.
|
||||||
|
string first_char = strzone(substring(file_line, 0, 1));
|
||||||
|
if (first_char == "#" || file_line == "") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
strunzone(first_char);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Actual Content Parsing
|
||||||
|
//
|
||||||
|
|
||||||
|
// Retrieving if its an allow or deny list.
|
||||||
|
if (parsing_state == 0) {
|
||||||
|
if (file_line == "allow:")
|
||||||
|
is_allow_not_deny = true;
|
||||||
|
else if (file_line == "deny:")
|
||||||
|
is_allow_not_deny = false;
|
||||||
|
else
|
||||||
|
error(strcat("MBOX_ParseMB2File: Not an allow/deny specifier - ", file_line));
|
||||||
|
|
||||||
|
// Now that we know the list, we can begin
|
||||||
|
// parsing the weapons inside of it.
|
||||||
|
parsing_state++;
|
||||||
|
} else if (parsing_state == 1) {
|
||||||
|
// Get the weapon ID from it's name.
|
||||||
|
weapon_id = WepDef_GetWeaponIDFromName(file_line);
|
||||||
|
|
||||||
|
if (weapon_id == W_NOWEP)
|
||||||
|
error(strcat("MBOX_ParseMB2File: Not a weapon - ", file_line));
|
||||||
|
|
||||||
|
// Fill the list with it.
|
||||||
|
mystery_box_weapons[weapons_parsed].weapon_id = weapon_id;
|
||||||
|
mystery_box_weapons[weapons_parsed].allowed = is_allow_not_deny;
|
||||||
|
weapons_parsed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
strunzone(file_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point, the file has been parsed with all of the
|
||||||
|
// allowed/denied weapons, now we have to automatically
|
||||||
|
// fill in the rest for the opposite list.
|
||||||
|
for (float i = weapons_parsed; i < MAX_BOX_WEAPONS; i++) {
|
||||||
|
// We need to pick an ID to assign that hasn't already
|
||||||
|
// been used.
|
||||||
|
weapon_id = MBOX_GetUnusedWeaponID();
|
||||||
|
mystery_box_weapons[i].weapon_id = weapon_id;
|
||||||
|
mystery_box_weapons[i].allowed = !is_allow_not_deny;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Precache the allowed weapons
|
||||||
|
MBOX_PrecacheWeaponContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// MBOX_LoadData()
|
||||||
|
// Seeks for either an .mb2 or .mbox file,
|
||||||
|
// and adds the contents into the Mystery Box
|
||||||
|
// weapon list.
|
||||||
|
//
|
||||||
|
void() MBOX_LoadData =
|
||||||
|
{
|
||||||
|
float mbox_file;
|
||||||
|
string file_path;
|
||||||
|
|
||||||
|
// Attempt 1: Seek for maps/mapname.mb2 (mbox-2)
|
||||||
|
file_path = strcat(mapname, ".mb2");
|
||||||
|
file_path = strcat("maps/", file_path);
|
||||||
|
mbox_file = fopen(file_path, FILE_READ);
|
||||||
|
if (mbox_file != -1) {
|
||||||
|
MBOX_ParseMB2File(mbox_file);
|
||||||
|
fclose(mbox_file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt 2: Seek for maps/mapname.mbox (mbox-1)
|
||||||
|
file_path = strcat(mapname, ".mbox");
|
||||||
|
file_path = strcat("maps/", file_path);
|
||||||
|
mbox_file = fopen(file_path, FILE_READ);
|
||||||
|
if (mbox_file != -1) {
|
||||||
|
MBOX_ParseMB1File(mbox_file);
|
||||||
|
fclose(mbox_file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt 3: Include All Weapons
|
||||||
|
for (float i = 0; i < MAX_BOX_WEAPONS; i++) {
|
||||||
|
mystery_box_weapons[i].weapon_id = MBOX_GetWeaponIDFromMB1(i);
|
||||||
|
mystery_box_weapons[i].allowed = true;
|
||||||
|
mystery_box_weapons[i].rarity = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Precache it all.
|
||||||
|
MBOX_PrecacheWeaponContent();
|
||||||
|
|
||||||
|
// Close the file pointer just in case.
|
||||||
|
fclose(mbox_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void() mystery_box =
|
void() mystery_box =
|
||||||
{
|
{
|
||||||
Load_Mbox_Data();
|
// Load and cache all of the allowed weapons into the hunk.
|
||||||
|
MBOX_LoadData();
|
||||||
|
|
||||||
precache_model ("models/machines/mystery.mdl");
|
//
|
||||||
precache_sound ("sounds/machines/mbox_open.wav");
|
// Set Default Stats for Compatibility
|
||||||
precache_sound ("sounds/machines/mbox_close.wav");
|
//
|
||||||
|
|
||||||
|
// Model
|
||||||
|
if (!self.model) {
|
||||||
|
self.model = "models/machines/mystery.mdl";
|
||||||
|
}
|
||||||
|
|
||||||
if (!(self.spawnflags & MBOX_SPAWNFLAG_NOLIGHT))
|
// Light Model
|
||||||
precache_model ("models/machines/mglow$.mdl");
|
if (!self.weapon2model) {
|
||||||
|
self.weapon2model = "models/machines/mglow$.mdl";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cost
|
||||||
|
if (!self.cost) {
|
||||||
|
self.cost = 950;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open Sound
|
||||||
|
if (!self.oldmodel) {
|
||||||
|
self.oldmodel = "sounds/machines/mbox_open.wav";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close Sound
|
||||||
|
if (!self.powerup_vo) {
|
||||||
|
self.powerup_vo = "sounds/machines/mbox_close.wav";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the custom presentation as globals
|
||||||
|
mystery_box_model = self.model;
|
||||||
|
mystery_box_glow_model = self.weapon2model;
|
||||||
|
mystery_box_open_sound = self.oldmodel;
|
||||||
|
mystery_box_close_sound = self.powerup_vo;
|
||||||
|
mystery_box_cost = self.cost;
|
||||||
|
|
||||||
|
precache_model(mystery_box_model);
|
||||||
|
|
||||||
|
if (!(self.spawnflags & MBOX_SPAWNFLAG_NOLIGHT))
|
||||||
|
precache_model (mystery_box_glow_model);
|
||||||
|
|
||||||
|
precache_sound(mystery_box_open_sound);
|
||||||
|
precache_sound(mystery_box_close_sound);
|
||||||
|
|
||||||
self.solid = SOLID_TRIGGER;
|
self.solid = SOLID_TRIGGER;
|
||||||
self.classname = "mystery";
|
self.classname = "mystery";
|
||||||
setorigin(self, self.origin);
|
setorigin(self, self.origin);
|
||||||
setmodel (self, "models/machines/mystery.mdl");
|
setmodel (self, mystery_box_model);
|
||||||
setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
|
setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
|
||||||
|
|
||||||
self.touch = mystery_touch;
|
self.touch = MBOX_Touch;
|
||||||
boxOrigin = self.origin;
|
|
||||||
|
|
||||||
|
mystery_box_start_origin = self.origin;
|
||||||
mystery_boxes[mystery_box_count] = self;
|
mystery_boxes[mystery_box_count] = self;
|
||||||
mystery_box_count++;
|
mystery_box_count++;
|
||||||
|
|
||||||
self.think = allocate_floating_weapons;
|
self.think = MBOX_AllocateTempEntities;
|
||||||
self.nextthink = time + 0.2;
|
self.nextthink = time + 0.2;
|
||||||
}
|
};
|
|
@ -62,6 +62,7 @@ inline void(entity ent) PU_FreeEnt =
|
||||||
ent.touch = SUB_Null;
|
ent.touch = SUB_Null;
|
||||||
ent.think = SUB_Null;
|
ent.think = SUB_Null;
|
||||||
ent.frame = 0;
|
ent.frame = 0;
|
||||||
|
ent.effects = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -665,6 +666,7 @@ void(vector where, float type) Spawn_Powerup =
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign the Power-Up model and sound
|
// Assign the Power-Up model and sound
|
||||||
|
powerup.effects = EF_FULLBRIGHT;
|
||||||
powerup.model = powerup.oldmodel = PU_ModelPath(powerup.walktype);
|
powerup.model = powerup.oldmodel = PU_ModelPath(powerup.walktype);
|
||||||
setmodel(powerup, powerup.model);
|
setmodel(powerup, powerup.model);
|
||||||
powerup.powerup_vo = PU_VoiceoverPath(powerup.walktype);
|
powerup.powerup_vo = PU_VoiceoverPath(powerup.walktype);
|
||||||
|
|
|
@ -34,7 +34,7 @@ void() setup_perk;
|
||||||
void() touch_perk;
|
void() touch_perk;
|
||||||
void(entity ent) MBOX_FreeEnt;
|
void(entity ent) MBOX_FreeEnt;
|
||||||
entity() MBOX_GetFreeEnt;
|
entity() MBOX_GetFreeEnt;
|
||||||
void() mystery_touch;
|
void() MBOX_Touch;
|
||||||
|
|
||||||
#define MBOX_SPAWNFLAG_NOLIGHT 2
|
#define MBOX_SPAWNFLAG_NOLIGHT 2
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ void() GameRestart_ResetMysteryBox =
|
||||||
|
|
||||||
// If the Mystery Box is not in its original
|
// If the Mystery Box is not in its original
|
||||||
// location.
|
// location.
|
||||||
if (mystery_box.origin != boxOrigin) {
|
if (mystery_box.origin != mystery_box_start_origin) {
|
||||||
mystery_box.model = "models/props/teddy.mdl";
|
mystery_box.model = "models/props/teddy.mdl";
|
||||||
mystery_box.frame = 2;
|
mystery_box.frame = 2;
|
||||||
mystery_box.classname = "mystery_box_tp_spot";
|
mystery_box.classname = "mystery_box_tp_spot";
|
||||||
|
@ -196,11 +196,11 @@ void() GameRestart_ResetMysteryBox =
|
||||||
MBOX_FreeEnt(mystery_box.goaldummy);
|
MBOX_FreeEnt(mystery_box.goaldummy);
|
||||||
|
|
||||||
// This isn't the normal spawn position
|
// This isn't the normal spawn position
|
||||||
if (mystery_box.origin != boxOrigin) {
|
if (mystery_box.origin != mystery_box_start_origin) {
|
||||||
// Find the original spot
|
// Find the original spot
|
||||||
entity original_box = find(world, classname, "mystery_box_tp_spot");
|
entity original_box = find(world, classname, "mystery_box_tp_spot");
|
||||||
while (original_box != world) {
|
while (original_box != world) {
|
||||||
if (original_box.origin == boxOrigin)
|
if (original_box.origin == mystery_box_start_origin)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
original_box = find(original_box, classname, "mystery_box_tp_spot");
|
original_box = find(original_box, classname, "mystery_box_tp_spot");
|
||||||
|
@ -212,20 +212,23 @@ void() GameRestart_ResetMysteryBox =
|
||||||
light.classname = "mystery_glow";
|
light.classname = "mystery_glow";
|
||||||
original_box.goaldummy = light;
|
original_box.goaldummy = light;
|
||||||
|
|
||||||
setmodel(light, "models/machines/mglow$.mdl");
|
setmodel(light, mystery_box_glow_model);
|
||||||
setorigin(light, original_box.origin);
|
setorigin(light, original_box.origin);
|
||||||
light.angles = original_box.angles;
|
light.angles = original_box.angles;
|
||||||
|
|
||||||
#ifdef FTE
|
#ifdef FTE
|
||||||
|
|
||||||
light.alpha = 0.5;
|
light.alpha = 0.5;
|
||||||
#endif
|
|
||||||
|
#endif // FTE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
original_box.touch = mystery_touch;
|
original_box.touch = MBOX_Touch;
|
||||||
original_box.solid = SOLID_TRIGGER;
|
original_box.solid = SOLID_TRIGGER;
|
||||||
original_box.classname = "mystery";
|
original_box.classname = "mystery";
|
||||||
setorigin(original_box, original_box.origin);
|
setorigin(original_box, original_box.origin);
|
||||||
setmodel(original_box, "models/machines/mystery.mdl");
|
setmodel(original_box, mystery_box_model);
|
||||||
setsize (original_box, VEC_HULL2_MIN, VEC_HULL2_MAX);
|
setsize (original_box, VEC_HULL2_MIN, VEC_HULL2_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
all weapon stats are stored here
|
all weapon stats are stored here
|
||||||
|
|
||||||
Copyright (C) 2021-2022 NZ:P Team
|
Copyright (C) 2021-2023 NZ:P Team
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
@ -4240,3 +4240,44 @@ float(float wep) GetWeaponZoomAmount =
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WepDef_GetWeaponIDFromName(weapon)
|
||||||
|
// Takes a string input and returns the weapon ID
|
||||||
|
// from the associated string. Will be deprecated
|
||||||
|
// when weapons are data-driven.
|
||||||
|
//
|
||||||
|
float(string weapon) WepDef_GetWeaponIDFromName =
|
||||||
|
{
|
||||||
|
switch(weapon) {
|
||||||
|
case "m1911": return W_COLT;
|
||||||
|
case "kar98k": return W_KAR;
|
||||||
|
case "thompson": return W_THOMPSON;
|
||||||
|
case "357_magnum": return W_357;
|
||||||
|
case "bar": return W_BAR;
|
||||||
|
case "ballistic_knife": return W_BK;
|
||||||
|
case "browning": return W_BROWNING;
|
||||||
|
case "double_barreled_shotgun": return W_DB;
|
||||||
|
case "fg42": return W_FG;
|
||||||
|
case "gewehr": return W_GEWEHR;
|
||||||
|
case "kar98k_scoped": return W_KAR_SCOPE;
|
||||||
|
case "m1_garand": return W_M1;
|
||||||
|
case "m1a1_carbine": return W_M1A1;
|
||||||
|
case "m2_flamethrower": return W_M2;
|
||||||
|
case "mp40": return W_MP40;
|
||||||
|
case "mg42": return W_MG;
|
||||||
|
case "panzerschreck": return W_PANZER;
|
||||||
|
case "ppsh-41": return W_PPSH;
|
||||||
|
case "ptrs-41": return W_PTRS;
|
||||||
|
case "ray_gun": return W_RAY;
|
||||||
|
case "sawed_off_shotgun": return W_SAWNOFF;
|
||||||
|
case "stg-44": return W_STG;
|
||||||
|
case "trenchgun": return W_TRENCH;
|
||||||
|
case "type_100": return W_TYPE;
|
||||||
|
case "wunderwaffe": return W_TESLA;
|
||||||
|
case "mp5k": return W_MP5K;
|
||||||
|
case "springfield": return W_SPRING;
|
||||||
|
default: return W_NOWEP;
|
||||||
|
}
|
||||||
|
return W_COLT;
|
||||||
|
}
|
Loading…
Reference in a new issue