Too lazy to comment
This commit is contained in:
407
mod_xj18/my_progs/client_mapvar.qc
Normal file
407
mod_xj18/my_progs/client_mapvar.qc
Normal file
@@ -0,0 +1,407 @@
|
||||
/*======================================================================
|
||||
Client Map Variables
|
||||
--------------------
|
||||
|
||||
Allows for binary (0/1) map variables to be stored with the map save
|
||||
system (parm1-16) by the engine. The top 6 parm variables are never used
|
||||
and can easily be turned into variables for the map to use.
|
||||
|
||||
======================================================================*/
|
||||
float MAPV_BITS = 22; // Bits used in each parm block
|
||||
float MAPV_BLCK = 6; // Blocks used (total parm's)
|
||||
float MAPV_TOTAL = 132; // Maximum amount of variables
|
||||
|
||||
float MAPV_QUERY = 1; // Point entity - Query value
|
||||
float MAPV_UPDATE = 2; // Point entity - Update value
|
||||
float MAPV_TOGGLE = 4; // Point entity - Toggle value
|
||||
float MAPV_MONSTERS = 32; // Monsters can use bmodel trigger
|
||||
|
||||
float bitflags[24]; // Bitflag values
|
||||
float mapvar[6]; // Map variables stored in savefile
|
||||
|
||||
//======================================================================
|
||||
/*QUAKED trigger_mapvar_query (.5 .7 1) (-8 -8 -16) (8 8 16) x
|
||||
Trigger target(s) based on mapvar
|
||||
-------- KEYS --------
|
||||
targetname : trigger entity (works with entity state system)
|
||||
count : Map Variable to check (range checks)
|
||||
target : Map variable == 0 fire these target(s)
|
||||
target2 : Map variable == 1 fire these target(s)
|
||||
noise : aframe switchable object
|
||||
wait : -1 = trigger once
|
||||
-------- SPAWNFLAGS --------
|
||||
-------- NOTES --------
|
||||
Trigger target(s) based on mapvar
|
||||
//-----------------------------------------------------------------------------
|
||||
/*QUAKED trigger_mapvar_update (.5 .7 1) (-8 -8 -16) (8 8 16) x
|
||||
Update the value of mapvar
|
||||
-------- KEYS --------
|
||||
targetname : trigger entity (works with entity state system)
|
||||
count : Map Variable to check (range checks)
|
||||
cnt : Value (0/1)
|
||||
target : Map variable == 0 fire these target(s)
|
||||
target2 : Map variable == 1 fire these target(s)
|
||||
noise : aframe switchable object
|
||||
wait : -1 = trigger once
|
||||
-------- SPAWNFLAGS --------
|
||||
-------- NOTES --------
|
||||
Update the value of mapvar
|
||||
//-----------------------------------------------------------------------------
|
||||
/*QUAKED trigger_mapvar_toggle (.5 .7 1) (-8 -8 -16) (8 8 16) x
|
||||
Toggle the value of mapvar
|
||||
-------- KEYS --------
|
||||
targetname : trigger entity (works with entity state system)
|
||||
count : Map Variable to check (range checks)
|
||||
target : Map variable == 0 fire these target(s)
|
||||
target2 : Map variable == 1 fire these target(s)
|
||||
noise : aframe switchable object
|
||||
wait : -1 = trigger once
|
||||
-------- SPAWNFLAGS --------
|
||||
-------- NOTES --------
|
||||
Toggle the value of mapvar
|
||||
======================================================================*/
|
||||
|
||||
// Setup the bitflag array (used in world.qc)
|
||||
void() mapvar_setuparray =
|
||||
{
|
||||
local float bitindex, bitpow;
|
||||
|
||||
// Setup loop and first bit
|
||||
bitindex = 0; bitpow = 1;
|
||||
while (bitindex < 24) {
|
||||
bitflags[bitindex] = bitpow;
|
||||
bitpow = bitpow * 2;
|
||||
bitindex = bitindex + 1;
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Reset all map variable banks to zero (used in client.qc)
|
||||
void() mapvar_reset =
|
||||
{
|
||||
local float mapv_bank;
|
||||
|
||||
mapv_bank = 0;
|
||||
while (mapv_bank < MAPV_BLCK) {
|
||||
mapvar[mapv_bank] = 0;
|
||||
mapv_bank = mapv_bank + 1;
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Read map variable from block/bits parms and return value
|
||||
float(float mapv_indx) query_mapvar =
|
||||
{
|
||||
local float mapv_bank, mapv_cell, mapv_bit;
|
||||
|
||||
// Work out parm and bitflag index
|
||||
mapv_bank = floor(mapv_indx/MAPV_BITS);
|
||||
mapv_cell = mapv_indx - (mapv_bank*MAPV_BITS);
|
||||
// Error check return value
|
||||
if (mapv_bank < 0 || mapv_bank >= MAPV_BLCK) mapv_bank = 0;
|
||||
if (mapv_cell < 0 || mapv_cell >= MAPV_BITS) mapv_cell = 0;
|
||||
// Find bitflag mask value
|
||||
mapv_bit = mapvar[mapv_bank] & bitflags[mapv_cell];
|
||||
|
||||
/* Debug info (not used anymore)
|
||||
dprint("Number ("); dprint(ftos(mapv_indx));
|
||||
dprint(") B/C ("); dprint(ftos(mapv_bank));
|
||||
dprint(" "); dprint(ftos(mapv_cell));
|
||||
dprint(") = ("); dprint(ftos(mapv_bit));
|
||||
dprint(")\n"); */
|
||||
|
||||
if (mapv_bit > 0) return TRUE;
|
||||
else return FALSE;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Update map variable from block/bits parms
|
||||
void(float mapv_indx, float mapv_val) update_mapvar =
|
||||
{
|
||||
local float mapv_bank, mapv_cell;
|
||||
|
||||
// Work out parm and bitflag index
|
||||
mapv_bank = floor(mapv_indx/MAPV_BITS);
|
||||
mapv_cell = mapv_indx - (mapv_bank*MAPV_BITS);
|
||||
// Error check return value
|
||||
if (mapv_bank < 0 || mapv_bank >= MAPV_BLCK) mapv_bank = 0;
|
||||
if (mapv_cell < 0 || mapv_cell >= MAPV_BITS) mapv_cell = 0;
|
||||
|
||||
// Remove any existing bitflag value
|
||||
mapvar[mapv_bank] = mapvar[mapv_bank] - (mapvar[mapv_bank] & bitflags[mapv_cell]);
|
||||
|
||||
// Is the bit value TRUE?
|
||||
if (mapv_val == TRUE) {
|
||||
mapvar[mapv_bank] = mapvar[mapv_bank] | bitflags[mapv_cell];
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Set a range of map variables (used in triggers.qc)
|
||||
void(vector mapv_range) mapvar_range =
|
||||
{
|
||||
local vector mapv_dest;
|
||||
local float mapv_swap, mapv_loop;
|
||||
|
||||
// Remove any negative or fractions
|
||||
mapv_dest_x = fabs(rint(mapv_range_x));
|
||||
mapv_dest_y = fabs(rint(mapv_range_y));
|
||||
mapv_dest_z = fabs(rint(mapv_range_z));
|
||||
|
||||
// Check for upper variable range
|
||||
if (mapv_dest_x >= (MAPV_BLCK*MAPV_BITS))
|
||||
mapv_dest_x = (MAPV_BLCK*MAPV_BITS) - 1;
|
||||
if (mapv_dest_y >= (MAPV_BLCK*MAPV_BITS))
|
||||
mapv_dest_y = (MAPV_BLCK*MAPV_BITS) - 1;
|
||||
if (mapv_dest_z > 1) mapv_dest_z = 1;
|
||||
|
||||
// Check for reverse order on range
|
||||
if (mapv_dest_x > mapv_dest_y) {
|
||||
mapv_swap = mapv_dest_x;
|
||||
mapv_dest_x = mapv_dest_y;
|
||||
mapv_dest_y = mapv_swap;
|
||||
}
|
||||
|
||||
// Count through range
|
||||
mapv_loop = mapv_dest_x;
|
||||
while (mapv_loop <= mapv_dest_y) {
|
||||
// Change map variable
|
||||
update_mapvar(mapv_loop, mapv_dest_z);
|
||||
mapv_loop = mapv_loop + 1;
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Display the value of all map variable parm blocks
|
||||
void() display_mapvar =
|
||||
{
|
||||
local float loopbank, loopcell, loopspace, loopval;
|
||||
|
||||
// Default return conditions (must be player and developer)
|
||||
if ( !(self.flags & FL_CLIENT) ) return;
|
||||
if (developer == 0) {
|
||||
sprint(self,"\b[IMPULSE]\b Only works in developer mode!\n");
|
||||
return;
|
||||
}
|
||||
// Has the map variable system been setup?
|
||||
if (!mapvar_cvar) {
|
||||
sprint(self,"\b[MAPVAR]\b System has not been setup yet!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset impulse and initialize variables
|
||||
self.impulse = 0;
|
||||
loopbank = loopcell = 0;
|
||||
|
||||
dprint("\n\b[MAPVAR]\b Current System Values\n");
|
||||
dprint("--------------------------------------\n");
|
||||
while (loopbank < MAPV_BLCK) {
|
||||
dprint("Bank "); dprint(ftos(loopbank)); dprint(" - ");
|
||||
loopcell = 0; loopspace = 4;
|
||||
while (loopcell < MAPV_BITS) {
|
||||
loopval = query_mapvar((loopbank*MAPV_BITS)+loopcell);
|
||||
dprint(ftos(loopval));
|
||||
|
||||
loopcell = loopcell+1;
|
||||
if (loopcell == loopspace) {
|
||||
dprint(" ");
|
||||
loopspace = loopspace+4;
|
||||
}
|
||||
}
|
||||
dprint("\n");
|
||||
loopbank = loopbank+1;
|
||||
}
|
||||
dprint("--------------------------------------\n");
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void() trigger_mapvar_base_use =
|
||||
{
|
||||
// Block entity state exceptions
|
||||
if (self.estate & ESTATE_BLOCK) return;
|
||||
// Is the trigger blocked? (trigger_once)
|
||||
if (self.attack_finished > time) return;
|
||||
|
||||
// UPDATE : Map Variable
|
||||
if (self.style == MAPV_UPDATE) {
|
||||
self.lefty = self.cnt;
|
||||
update_mapvar(self.count, self.cnt);
|
||||
}
|
||||
// TOGGLE : map variable
|
||||
else if (self.style == MAPV_TOGGLE) {
|
||||
self.lefty = query_mapvar(self.count);
|
||||
self.lefty = 1 - self.lefty;
|
||||
update_mapvar(self.count, self.lefty);
|
||||
}
|
||||
// QUERY : map variable
|
||||
else {
|
||||
self.lefty = query_mapvar(self.count);
|
||||
}
|
||||
|
||||
// Check for On/Off target(s)
|
||||
if (self.lefty == FALSE) {
|
||||
if (self.target != "") trigger_strs(self.target, activator);
|
||||
}
|
||||
else {
|
||||
if (self.target2 != "") trigger_strs(self.target2, activator);
|
||||
}
|
||||
|
||||
// Check for switchable bmodel
|
||||
if (self.noise != "") {
|
||||
// Check if entity exists first
|
||||
if (!self.oldenemy)
|
||||
self.oldenemy = find(world, targetname, self.noise);
|
||||
// Only work with Bmodel entities (usually aframes)
|
||||
if (self.oldenemy.bsporigin) {
|
||||
// Flashing (ON) is +0frame ; Static (OFF) is +aframe
|
||||
if (self.lefty == TRUE) self.oldenemy.frame = 0;
|
||||
else self.oldenemy.frame = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for fire once condition and wait timer
|
||||
if (self.wait < 0) self.attack_finished = LARGE_TIMER;
|
||||
else self.attack_finished = time + self.wait;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void() trigger_mapvar_base =
|
||||
{
|
||||
// Check for any missing keys
|
||||
if (self.targetname == "") dprint("\b[MAPVAR]\b Missing targetname!\n");
|
||||
// Remove any negative or fractions
|
||||
self.count = fabs(rint(self.count));
|
||||
|
||||
// Check for upper variable range
|
||||
if (self.count >= (MAPV_BLCK*MAPV_BITS))
|
||||
self.count = (MAPV_BLCK*MAPV_BITS) - 1;
|
||||
|
||||
// Check for bitflag value range
|
||||
if (self.cnt < FALSE || self.cnt > TRUE) self.cnt = FALSE;
|
||||
|
||||
// Setup Entity State functionality
|
||||
if (self.targetname != "") self.use = entity_state_use;
|
||||
self.estate_use = trigger_mapvar_base_use;
|
||||
self.estate = ESTATE_ON;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void() trigger_mapvar_query =
|
||||
{
|
||||
self.classtype = CT_MAPVAR;
|
||||
self.style = MAPV_QUERY;
|
||||
trigger_mapvar_base();
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void() trigger_mapvar_update =
|
||||
{
|
||||
self.classtype = CT_MAPVAR;
|
||||
self.style = MAPV_UPDATE;
|
||||
trigger_mapvar_base();
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void() trigger_mapvar_toggle =
|
||||
{
|
||||
self.classtype = CT_MAPVAR;
|
||||
self.style = MAPV_TOGGLE;
|
||||
trigger_mapvar_base();
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
/*QUAKED trigger_mapvar_multiple (0.5 0 0.5) ? x x x x x MONSTERS STARTOFF x Not_Easy Not_Normal Not_Hard Not_DM
|
||||
Touch trigger target(s) based on mapvar
|
||||
------- KEYS --------
|
||||
targetname : trigger entity (works with entity state system)
|
||||
count : Map Variable to check (range checks)
|
||||
target : Map variable == 0 fire these target(s)
|
||||
message : Map variable == 0 message to display
|
||||
target2 : Map variable == 1 fire these target(s)
|
||||
message2: Map variable == 1 message to display
|
||||
health : Can be damaged instead of touched
|
||||
wait : time between re-triggering
|
||||
delay : delay before firing (after being triggered)
|
||||
angle : Facing Direction for trigger to work, use "360" for angle 0.
|
||||
sounds : 1=Secret,2=talk(def),3=switch,4=silent,5=custom,6=secret2
|
||||
noise : custom sound to play when triggered
|
||||
-------- SPAWNFLAGS --------
|
||||
MONSTER : can be touched/triggered by monsters
|
||||
STARTOFF : Requires trigger to activate
|
||||
------- NOTES --------
|
||||
Touch trigger target(s) based on mapvar
|
||||
======================================================================*/
|
||||
void() trigger_mapvar_multiple_fire =
|
||||
{
|
||||
if (self.attack_finished > time) return; // Trigger once?
|
||||
|
||||
// Find out map variable value
|
||||
self.lefty = query_mapvar(self.count);
|
||||
// Switch around target/message strings
|
||||
if (self.lefty == FALSE) {
|
||||
self.target = self.idle_sound;
|
||||
self.message = self.idle_soundcom;
|
||||
}
|
||||
else {
|
||||
self.target = self.idle_sound2;
|
||||
self.message = self.idle_soundcom2;
|
||||
}
|
||||
|
||||
// Play the sound ON the trigger, NOT the activator
|
||||
if (self.noise != "") sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
|
||||
|
||||
// Original trigger_multiple activator behaviour
|
||||
activator = self.bmodel_act;
|
||||
SUB_UseTargets();
|
||||
|
||||
// Is the trigger repeatable?
|
||||
if (self.wait > 0) {
|
||||
self.attack_finished = time + self.wait;
|
||||
self.nextthink = self.attack_finished;
|
||||
self.think = self.estate_on;
|
||||
}
|
||||
else {
|
||||
// TRIGGER_ONCE functionality
|
||||
self.attack_finished = LARGE_TIMER;
|
||||
self.estate_off();
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void() trigger_mapvar_multiple =
|
||||
{
|
||||
if (check_bmodel_keys()) return; // Check for bmodel errors
|
||||
|
||||
// Remove excessive spawnflags not used
|
||||
self.lefty = 0;
|
||||
if (self.spawnflags & MAPV_MONSTERS) self.lefty = self.lefty | MAPV_MONSTERS;
|
||||
if (self.spawnflags & ENT_STARTOFF) self.lefty = self.lefty | ENT_STARTOFF;
|
||||
self.spawnflags = self.lefty;
|
||||
|
||||
// Remove any negative or fractions
|
||||
self.count = fabs(rint(self.count));
|
||||
|
||||
// Check for upper variable range
|
||||
if (self.count >= (MAPV_BLCK*MAPV_BITS))
|
||||
self.count = (MAPV_BLCK*MAPV_BITS) - 1;
|
||||
|
||||
// Typical bmodel trigger setup
|
||||
trigger_bmodel_sounds();
|
||||
self.classtype = CT_MAPVAR;
|
||||
InitTrigger ();
|
||||
if (!self.wait) self.wait = 0.2;
|
||||
|
||||
// Save all entity for later
|
||||
self.idle_sound = self.target;
|
||||
self.idle_sound2 = self.target2;
|
||||
self.idle_soundcom = self.message;
|
||||
self.idle_soundcom2 = self.message2;
|
||||
|
||||
// Reset all strings to prevent SUB_UseTargets errors
|
||||
self.target = ""; self.target2 = "";
|
||||
self.message = ""; self.message2 = "";
|
||||
|
||||
// Setup Entity State functionality
|
||||
self.estate_fire = trigger_mapvar_multiple_fire;
|
||||
trigger_bmodel_setup();
|
||||
};
|
||||
Reference in New Issue
Block a user