Files
quakemapping/mod_ad_dev/my_progs/part_manage.qc
2019-12-30 22:24:44 +01:00

547 lines
24 KiB
Plaintext

//======================================================================
// Particle System
//======================================================================
// Particle management
float PARTICLE_MAXENTS = 1024; // Maximum amount of particles active (default)
float PARTICLE_BANK = 64; // How many particle in each setup bank
float PARTICLE_BUFFER = 128; // How many particle to create before unlock
float part_message; // Timer for particle message (every 3s)
entity part_control; // Particle setup entity (drives nextthink)
entity part_start; // Pointers to start/end particle chain
entity part_end;
entity part_free; // Current particle entity
float part_total; // Currently active particles
float part_max; // Maximum active particles
entity part; // Spawning particle emitters and particles
//----------------------------------------------------------------------
// Particle emitter parameters
float PARTICLE_START_OFF = 1; // Particle emitter starts OFF
float PARTICLE_START_ON = 2; // Particle emitter starts ON
float PARTICLE_WEATHER_SNOW = 8; // Weather snow - White
.float particlemax; // Maximum about of ACTIVE particles per map
.entity entchain; // Entity pointer to next entity in chain
.entity part_emitter; // Particle emitter link on any entity
.entity pemit_source; // Source/owner of particle emitter
.entity pemit_target; // Particle emitter target entity
.float target_valid; // Test condition for valid target entity (not self or world)
.float part_style; // Pre-defined particle styles
.float pemit_tcount; // Particle emitter, total active particles
.float part_active; // Is the particle active or not
.float start_delay; // Particle emitter start delay
.float dpp_only; // Is the particle a DPP only effect?
.string dpp_name; // DP particle effect name in effectinfo.txt file
.float dpp_wait; // DP particle re-trigger timer
.float dpp_rnd; // DP particle random multiplier for time
.vector dpp_vel; // Direction of DP particles to move towards
//----------------------------------------------------------------------
// Particle style parameters
.string spr_name1; // Sprite string name 1 (uses defs)
.string spr_name2; // Sprite string name 2
.string spr_name3; // Sprite string name 3
.float spr_frame; // Sprite frame type 1=all, 2=light, 3=dark
.float part_limit; // Maximum amount of particles to emit
.float part_life; // Life time
.vector part_ofs; // Offset from emitter
.float part_veltype; // Velocity types
.vector part_velbase; // Base velocity (always this direction)
.vector part_vel; // Random Velocity direction (vel+random*vel)
.vector part_velrand; // Extra random velocity wobble
.float part_velrot; // Velocity rotation (Y axis only)
.vector part_vol; // Spawning volume
.float circular_angle; // Circular rotation angle
.float part_movetype; // Movetype of particle
.float wakeup_dist; // Wake up distance for particle emitter
.float wakeup_timer; // How often to check distance check
.float spawn_base; // Spawn rate - base value
.float spawn_rand; // Spawn rate - random adjustment
// Compiler forward links
void() setup_particleprecache;
//----------------------------------------------------------------------
// The particle is finished with, update emitter particle counter
//----------------------------------------------------------------------
void() finish_particle =
{
if (self.classtype != CT_PARTICLE) {
dprint("\b[PARTICLE_RETURN]\b This is not a particle!?!\n");
}
else {
if (self.owner.pemit_tcount > 0)
self.owner.pemit_tcount = self.owner.pemit_tcount - 1;
self.velocity = VEC_ORIGIN; // no more movement
self.avelocity = VEC_ORIGIN;
self.origin = VEC_ORIGIN;
self.part_active = FALSE; // Finished with particle
setmodel(self, ""); // Remove from world
self.owner = world; // No owner anymore
self.skin = self.frame = self.flags = FALSE;
self.gravity = 1;
// Update active particle total
if (part_total > 1) part_total = part_total - 1;
if (part_free.classtype != CT_PARTICLE) {
dprint("\b[PARTICLE_RETURN]\b Current free particle is wrong classtype!!\n");
}
else {
// Add particle back into central particle list
self.entchain = part_free.entchain; // link new particle forward in chain
part_free.entchain = self; // link free particle to new particle
if (part_debug == 2) {
dprint("Return Free ("); dprint(ftos(part_free.cnt));
dprint(") Next ("); dprint(ftos(part_free.entchain.cnt));
dprint(")\n");
}
}
}
};
//----------------------------------------------------------------------
// All requests for particles must go through one function
//----------------------------------------------------------------------
entity() fetch_particle =
{
local entity tpart_ret;
tpart_ret = world; // Default - no particle returned
// Make sure the system has 2 banks of particles setup first!
if (part_control.count < PARTICLE_BUFFER) return tpart_ret;
// Display particle limits if skill set to a debug number
if (part_debug == 1) {
sprint(client_ent, "CREATE Particle ("); sprint(client_ent, ftos(part_total));
sprint(client_ent, "/"); sprint(client_ent, ftos(part_max));
sprint(client_ent, ")\n");
}
// Are there any free particles?
if (part_total >= part_max - 1) {
if (part_message < time) {
dprint("\b[PARTICLE]\b current limit ("); dprint(ftos(part_max));
dprint(") too low!\n");
part_message = time + 5; // interval console spam
}
}
else {
if (part_free.classtype != CT_PARTICLE) {
dprint("\b[PARTICLE_FETCH]\b Current free particle is wrong classtype!!\n");
}
else if (part_free.entchain.classtype != CT_PARTICLE) {
dprint("\b[PARTICLE_FETCH]\b Next free particle is wrong classtype!!\n");
dprint("Free ("); dprint(ftos(part_free.cnt));
dprint(") Ctype ("); dprint(ftos(part_free.classtype));
dprint(") Next ("); dprint(ftos(part_free.entchain.cnt));
dprint(") Ctype ("); dprint(ftos(part_free.entchain.classtype));
dprint(")\n");
}
else {
tpart_ret = part_free.entchain; // return next free particle
part_free.entchain = tpart_ret.entchain; // Skip forward in the chain
// Update currently active particle total
part_total = part_total + 1;
tpart_ret.part_active = TRUE;
if (part_debug == 2) {
dprint("Fetch Free ("); dprint(ftos(part_free.cnt));
dprint(") return ("); dprint(ftos(tpart_ret.cnt));
dprint(")\n");
}
}
}
return (tpart_ret);
};
//----------------------------------------------------------------------
// Generate a chain of entities (one block at a time)
//----------------------------------------------------------------------
void() generate_particlechain =
{
local entity part_prev, part_first;
local float pcount;
// Reset all variables
part_first = part_prev = part = world;
pcount = 0;
// Is there anymore particles need to be created?
if (self.count + 1 < part_max) {
dprint("\b[PCHAIN]\b Part bank (");
dprint(ftos(self.count)); dprint(" / ");
dprint(ftos(part_max)); dprint(")\n");
while (pcount < PARTICLE_BANK) {
// Create a new particle entity
part = spawn();
part.solid = SOLID_NOT;
part.owner = world;
part.part_active = FALSE;
part.classname = "particle";
part.classtype = CT_PARTICLE;
// If DP engine active remove particle shadow
if (engine == ENG_DPEXT) part.effects = part.effects + EF_NOSHADOW;
part.cnt = self.count + pcount;
pcount = pcount + 1; // Increase loop
//----------------------------------------------------------------------
// Link particle chains together
if (part_prev.classtype != CT_PARTICLE)
part_first = part; // NEW CHAIN - setup all entity pointers
else part_prev.entchain = part; // EXISTING CHAIN - Link particles together
part_prev = part; // Setup previous particle in chain
//----------------------------------------------------------------------
}
// Update total particles generated
self.count = self.count + PARTICLE_BANK;
//----------------------------------------------------------------------
// Are there any previous banks of particles?
if (part_start.classtype != CT_PARTICLE) {
// NEW BANK - Setup start/end particle and close chain
part_start = part.entchain = part_first;
part_free = part_first.entchain; // Move forward 1
part_end = part;
}
else {
// EXISTING BANK - Link new bank to existing banks
part_end.entchain = part_first; // Link end and first of new bank together
part.entchain = part_start; // Link current and start together
part_end = part; // Move end of bank forward
}
//----------------------------------------------------------------------
}
//----------------------------------------------------------------------
// Is there anymore particles need to be created?
if (self.count + 1 < part_max) {
self.think = generate_particlechain;
self.nextthink = time + 0.2;
}
// Finished generating particle banks
else self.waitmin = FALSE;
};
//----------------------------------------------------------------------
// Setup particle chain in small banks
//----------------------------------------------------------------------
void() setup_particlechain =
{
// Pre-cache all sprites
setup_particleprecache();
if (part_control.classtype != CT_PARTICLECONT) {
part_control = spawn();
part_control.solid = SOLID_NOT;
part_control.classtype = CT_PARTICLECONT;
dprint("\b[PCHAIN]\b Creating controller\n");
part_free = part_end = part_start = world;
part_total = part_control.count = 0;
part_control.waitmin = TRUE;
}
// Setup next think
part_control.think = generate_particlechain;
part_control.nextthink = time + 0.3;
};
//----------------------------------------------------------------------
// Extend particle chain (used by quickload issues)
//----------------------------------------------------------------------
void() extend_particlechain =
{
local float new_part_max;
// Check for particle chain controller FIRST!
if (part_control.classtype != CT_PARTICLECONT) return;
// Check if particle bank setup is running already
if (part_control.waitmin) return;
// Make sure particle banks are reset to default if low
if (part_max < PARTICLE_MAXENTS) new_part_max = PARTICLE_MAXENTS;
// Check for any worldspawn override value
if (world.particlemax > 0) {
if (new_part_max < world.particlemax)
new_part_max = world.particlemax;
}
// Does the particle bank max need to change?
if (part_max > new_part_max) return;
else part_max = new_part_max;
dprint("\b[WORLD]\b New max particles (");
dprint(ftos(part_max)); dprint(")\n");
// Setup next think
part_control.think = generate_particlechain;
part_control.nextthink = time + 0.3;
part_control.waitmin = TRUE;
};
//----------------------------------------------------------------------
float PARTICLE_ORIGIN_VOL = 0; // Pick random point inside volume
float PARTICLE_ORIGIN_CIRCLE = 1; // Move around circumference of circle
float PARTICLE_ORIGIN_RANDCIRCLE = 2; // Randomly point on circumference
float PARTICLE_ORIGIN_SPIRAL = 3; // Spiral outwards to circumference
float PARTICLE_ORIGIN_CENTER = 5; // Explosion style from center
//----------------------------------------------------------------------
// particle BURST explosions
float PARTICLE_BURST_YELLOW = 1; // gold, yellow, yellow
float PARTICLE_BURST_GREEN = 2; // light green, green, green
float PARTICLE_BURST_RED = 4; // grey, red, red
float PARTICLE_BURST_BLUE = 8; // blue, grey, blue
float PARTICLE_BURST_PURPLE = 16; // purple, grey, purple
float PARTICLE_BURST_FIRE = 32; // gold, red, grey (used by ogre)
float PARTICLE_BURST_WHITE = 64; // white, grey, grey
float PARTICLE_BURST_RING = 256; // Circular particle burst
float PARTICLE_BURST_CENTER = 512; // Central particle burst
float PARTICLE_BURST_UPWARD = 1024; // Drifting upward burst
float PARTICLE_BURST_SHOCKWAVE = 4096; // Floor impact shockwave
float PARTICLE_BURST_SKULLUP = 8192; // Skull wizard teleport
float PARTICLE_BURST_LOSTUP = 16384; // Lost souls particle burn
float PARTICLE_BURST_MINOTAUR = 32768; // Minotaur magic attack over
//----------------------------------------------------------------------
// Map referenced particles
float PARTICLE_STYLE_CUSTOM = 1; // Custom particle defined in map
float PARTICLE_STYLE_WEATHER = 5; // Various weather type effects
float PARTICLE_STYLE_PORTAL = 10; // White dot/bubbles floating outwards (volume)
float PARTICLE_STYLE_JUMPPAD = 15; // Spiral pattern floating upward
float PARTICLE_STYLE_FCIRCLE = 20; // Yellow dots floating upwards from circle on floor
float PARTICLE_STYLE_FFIELD = 25; // Volume Forcefield custom direction
// Code referenced particles
float PARTICLE_STYLE_EMPTY = 0; // Particle emitter is dead/broken
float PARTICLE_STYLE_BOOK = 50; // Rotating white runes floating upwards (CLOSED)
float PARTICLE_STYLE_OPENBOOK = 55; // Particle dots based on book colour (OPEN)
float PARTICLE_STYLE_ELECTRIC = 65; // White/blue sparks floating towards target
float PARTICLE_STYLE_FLAMES = 70; // Small Flame Yellow/red embers
float PARTICLE_STYLE_FLAMET = 72; // Small Torch Yellow/red embers
float PARTICLE_STYLE_FLAMEL = 75; // Large Flame and lots of particles
float PARTICLE_STYLE_SMOKE = 80; // DP only effect, velocity driven smoke
float PARTICLE_STYLE_RESPAWN = 100; // Red/yellow dots spawning from single point
float PARTICLE_STYLE_MEGAH = 105; // Red dot/heal particles from center
float PARTICLE_STYLE_ARMOR = 110; // Green/Yellow/Red dots floating up
float PARTICLE_STYLE_KEYSILVER = 120; // Blue explosion from top of key
float PARTICLE_STYLE_KEYGOLD = 122; // Yellow explosion from top of key
float PARTICLE_STYLE_KEYRED = 124; // Red explosion from top of key
float PARTICLE_STYLE_KEYGREEN = 126; // Green explosion from top of key
float PARTICLE_STYLE_KEYPURPLE = 128; // Purple explosion from top of key
float PARTICLE_STYLE_KEYWHITE = 130; // White explosion from top of key
float PARTICLE_STYLE_SIGIL = 140; // Purple explosion from center of rune
float PARTICLE_STYLE_ALTAR = 145; // Red/yellow dots raising around altar
float PARTICLE_STYLE_SKILL = 150; // Burst of red/yellow from skill column
float PARTICLE_STYLE_BSKILL = 152; // Burst of blue particles
float PARTICLE_STYLE_GSKILL = 154; // Burst of green particles
float PARTICLE_STYLE_PSKILL = 156; // Burst of purple particles
float PARTICLE_STYLE_BACKPACK = 175; // Grey/White dots from center
float PARTICLE_STYLE_SUIT = 200; // Green dots rising up
float PARTICLE_STYLE_PENT = 210; // Red/Black dots from center
float PARTICLE_STYLE_SRING = 220; // Yellow dots falling down
float PARTICLE_STYLE_QUAD = 230; // Blue dots from center
float PARTICLE_STYLE_TOMEOFP = 240; // Yellow explosion from skull
float PARTICLE_STYLE_SHARP = 250; // Purple dots from center
float PARTICLE_STYLE_PIERCE = 260; // Purple dots from center
float PARTICLE_STYLE_WETSUIT = 270; // Blue dots rising up
//----------------------------------------------------------------------
// Darkplaces custom particles defined in effectinfo.txt
//void(entity gibent, float gibpoison) DPP_blood_trail;
// DarkPlaces Particles definition block names
// defined in effectinfo.txt (location - root of mod directory)
string DPP_TRBLOOD = "TR_BLOOD"; // Blood TRail for model flag
string DPP_ITSBLOOD = "TR_ITSBLOOD"; // Blood TRail (extra blood)
string DPP_TRSBLOOD = "TR_SBLOOD"; // Stone Blood TRail for model flag
string DPP_TRPBLOOD = "TR_PBLOOD"; // Poison Blood TRail for model flag
string DPP_TRLASER = "TR_LASER"; // Laser particle TRail
string DPP_TEEXPLODE = "TE_EXPLOSION"; // Default particle explosion
string DPP_TRPLASMA = "TR_PLASMA"; // Plasma particle TRail
string DPP_TEPLASMA = "TE_PLASMA"; // Plasma particle explosion
string DPP_TEPLASMABIG = "TE_PLASMABIG";// Plasma Big explosion
string DPP_TRPOISON = "TR_POISON"; // Poison particle TRail
string DPP_TEPOISON = "TE_POISON"; // Poison particle explosion
string DPP_TEPOISONMED = "TE_POISONBIG";// Poison Medium explosion
string DPP_TEBSMOKE = "TE_BSMOKE"; // A burst of Smoke/Steam
string DPP_TEBFLAME = "TE_BFLAME"; // A burst of red flame (smoke)
string DPP_TEBPOISON = "TE_BPOISON"; // A burst of green poison (smoke)
string DPP_PORTALFRONT = "DPP_ITSPORTALFRONT"; // 0,180 angle
string DPP_PORTALSIDE = "DPP_ITSPORTALSIDE"; // 90,270 angle
string DPP_PORTALDOWN = "DPP_ITSPORTALDOWN"; // -2 angle
string DPP_PORTALUP = "DPP_ITSPORTALUP"; // -1 angle
string DPP_FCIRCLE = "DPP_ITSFCIRCLE";
string DPP_JUMPPAD = "DPP_ITSJUMPPAD";
string DPP_BOOKBLUE = "DPP_ITSBOOKBLUE";
string DPP_BOOKRED = "DPP_ITSBOOKRED";
string DPP_BOOKGOLD = "DPP_ITSBOOKGOLD";
string DPP_OPENBOOKBLUE = "DPP_ITSOPENBOOKBLUE";
string DPP_OPENBOOKRED = "DPP_ITSOPENBOOKRED";
string DPP_OPENBOOKGOLD = "DPP_ITSOPENBOOKGOLD";
string DPP_ELECTRIC = "DPP_ITSELECTRIC";
string DPP_FLAMES = "DPP_ITSSFLAME";
string DPP_FLAMET = "DPP_ITSTFLAME";
string DPP_FLAMEL = "DPP_ITSLFLAME";
string DPP_SKILLPILLAR = "DPP_ITSSKILLPILLAR";
string DPP_BSKILLPILLAR = "DPP_ITSBSKILLPILLAR";
string DPP_GSKILLPILLAR = "DPP_ITSGSKILLPILLAR";
string DPP_PSKILLPILLAR = "DPP_ITSPSKILLPILLAR";
string DPP_ALTARRED = "DPP_ITSALTARRED";
string DPP_ALTARGREY = "DPP_ITSALTARGREY";
string DPP_RESPAWN = "DPP_ITSRESPAWN";
string DPP_MEGAH = "DPP_ITSMEGAH";
string DPP_ARMOR1 = "DPP_ITSARMOR1";
string DPP_ARMOR2 = "DPP_ITSARMOR2";
string DPP_ARMOR2BLUE = "DPP_ITSARMOR2BLUE";
string DPP_ARMOR3 = "DPP_ITSARMOR3";
string DPP_WEAPON = "DPP_ITSWEAPON";
string DPP_KEYSILVER = "DPP_ITSSILVERKEY";
string DPP_KEYGOLD = "DPP_ITSGOLDKEY";
string DPP_KEYRED = "DPP_ITSREDKEY";
string DPP_KEYGREEN = "DPP_ITSGREENKEY";
string DPP_KEYPURPLE = "DPP_ITSPURPLEKEY";
string DPP_KEYWHITE = "DPP_ITSWHITEKEY";
string DPP_SIGIL = "DPP_ITSSIGIL";
string DPP_BACKPACK = "DPP_ITSBACKPACK";
string DPP_BACKPACKB = "DPP_ITSBACKPACKB";
string DPP_BACKPACKG = "DPP_ITSBACKPACKG";
string DPP_BACKPACKR = "DPP_ITSBACKPACKR";
string DPP_BACKPACKY = "DPP_ITSBACKPACKY";
string DPP_SUIT = "DPP_ITSSUIT";
string DPP_PENT = "DPP_ITSPENT";
string DPP_SRING = "DPP_ITSSRING";
string DPP_QUAD = "DPP_ITSQUAD";
string DPP_TOMEOFP = "DPP_ITSTOMEOFP";
string DPP_SHARP = "DPP_ITSSHARP";
string DPP_SHARPG = "DPP_ITSSHARPG";
string DPP_PIERCE = "DPP_ITSPIERCE";
string DPP_WETSUIT = "DPP_ITSWETSUIT";
// Special trigger effects
string DPP_TEVORESPIKE = "TE_VORESPIKE";
string DPP_WRAITHEXPLODE = "DPP_ITSWRAITHEXPLODE";
string DPP_INTERACTIVE = "DPP_ITSINTERACTIVE";
string DPP_BURSTFLAME = "DPP_ITSFLAME_BURST";
string DPP_FCIRCLE_RING = "DPP_ITSFCIRCLE_RING";
string DPP_SIGILPICKUP = "DPP_ITSSIGIL_PICKUP";
string DPP_BURSTSHOCKWAVE1 = "DPP_ITSBURSTSHOCKWAVE1";
string DPP_BURSTSHOCKWAVE2 = "DPP_ITSBURSTSHOCKWAVE2";
string DPP_PYROFLAME1 = "DPP_ITSPYROFLAME1";
string DPP_PYROFLAME2 = "DPP_ITSPYROFLAME2";
string DPP_PYROFLAME3 = "DPP_ITSPYROFLAME3";
// Velocity driven smoke
string DPP_VELSMOKEGREY1 = "DPP_ITSVELSMOKEGREY1";
string DPP_VELSMOKEGREY2 = "DPP_ITSVELSMOKEGREY2";
string DPP_VELSMOKEWHITE = "DPP_ITSVELSMOKEWHITE";
string DPP_VELSMOKETOXIC = "DPP_ITSVELSMOKETOXIC";
string DPP_VELSMOKEGREEN = "DPP_ITSVELSMOKEGREEN";
string DPP_VELSMOKEPURPLE = "DPP_ITSVELSMOKEPURPLE";
string DPP_VELSMOKERED = "DPP_ITSVELSMOKERED";
string DPP_VELSMOKEFIRE = "DPP_ITSVELSMOKEFIRE";
// Respawn effects
string DPP_RINGPARTY = "DPP_ITSPART_RINGY";
string DPP_RINGPARTG = "DPP_ITSPART_RINGG";
string DPP_RINGPARTR = "DPP_ITSPART_RINGR";
string DPP_RINGPARTB = "DPP_ITSPART_RINGB";
string DPP_RINGPARTP = "DPP_ITSPART_RINGP";
string DPP_RINGPARTW = "DPP_ITSPART_RINGW";
string DPP_BURSTPARTY = "DPP_ITSPART_BURSTY";
string DPP_BURSTPARTG = "DPP_ITSPART_BURSTG";
string DPP_BURSTPARTR = "DPP_ITSPART_BURSTR";
string DPP_BURSTPARTB = "DPP_ITSPART_BURSTB";
string DPP_BURSTPARTP = "DPP_ITSPART_BURSTP";
string DPP_BURSTPARTW = "DPP_ITSPART_BURSTW";
// Forcefield volumes
string DPP_FFIELDPARTY = "DPP_ITSPART_FFIELDY";
string DPP_FFIELDPARTG = "DPP_ITSPART_FFIELDG";
string DPP_FFIELDPARTR = "DPP_ITSPART_FFIELDR";
string DPP_FFIELDPARTB = "DPP_ITSPART_FFIELDB";
string DPP_FFIELDPARTP = "DPP_ITSPART_FFIELDP";
string DPP_FFIELDPARTW = "DPP_ITSPART_FFIELDW";
//----------------------------------------------------------------------
// GENERIC particle filename strings
string PART_BUBBLE_BLUE = "progs/s_bubble_blue1.spr";
string PART_DOTMED_BLUE = "progs/s_dotmed_blue.spr";
string PART_DOTSML_BLUE = "progs/s_dotsml_blue.spr";
string PART_DOTMED_DBLUE = "progs/s_dotmed_dblue.spr";
string PART_DOTSML_DBLUE = "progs/s_dotsml_dblue.spr";
string PART_BUBBLE_YELLOW = "progs/s_bubble_yell.spr";
string PART_DOTMED_YELLOW = "progs/s_dotmed_yell.spr";
string PART_DOTSML_YELLOW = "progs/s_dotsml_yell.spr";
string PART_DOTSML_GOLD = "progs/s_dotsml_gold.spr";
string PART_BUBBLE_RED = "progs/s_bubble_red1.spr";
string PART_DOTMED_RED = "progs/s_dotmed_red.spr";
string PART_DOTSML_RED = "progs/s_dotsml_red.spr";
string PART_DOTMED_GREEN = "progs/s_dotmed_grn.spr";
string PART_DOTSML_GREEN = "progs/s_dotsml_grn.spr";
string PART_DOTMED_LGREEN = "progs/s_dotmed_lgrn.spr";
string PART_DOTSML_LGREEN = "progs/s_dotsml_lgrn.spr";
string PART_DOTSML_PURP = "progs/s_dotsml_purp.spr";
string PART_DOTMED_PURP = "progs/s_dotmed_purp.spr";
string PART_BUBBLE_WHITE = "progs/s_bubble_wht.spr";
string PART_DOTSML_WHITE = "progs/s_dotsml_wht.spr";
string PART_DOTMED_GREY = "progs/s_dotmed_grey.spr";
string PART_DOTSML_GREY = "progs/s_dotsml_grey.spr";
// SPECIFIC particle filename strings
string PART_TORCH1 = "progs/s_dotmed_tor1.spr";
string PART_TORCH2 = "progs/s_dotmed_tor2.spr";
string PART_BOOKRUNE1 = "progs/s_bookrune1.spr";
string PART_BOOKRUNE2 = "progs/s_bookrune2.spr";
//----------------------------------------------------------------------
// Particle sprites
//----------------------------------------------------------------------
void() setup_particleprecache =
{
precache_model (PART_TORCH1); // Embers - Red/Yellow
precache_model (PART_TORCH2); // Embers - Red/Yellow
precache_model (PART_BOOKRUNE1); // Celtic Book Runes
precache_model (PART_BOOKRUNE2); // Celtic Book Runes
precache_model (PART_BUBBLE_BLUE); // Bubbles - Blue
precache_model (PART_DOTMED_BLUE); // Dots - Medium Blue
precache_model (PART_DOTSML_BLUE); // Dots - Small Blue
precache_model (PART_DOTMED_DBLUE); // Dots - Medium Dark Blue
precache_model (PART_DOTSML_DBLUE); // Dots - Small Dark Blue
precache_model (PART_BUBBLE_YELLOW); // Bubbles - Yellow
precache_model (PART_DOTMED_YELLOW); // Dots - Medium Yellow
precache_model (PART_DOTSML_YELLOW); // Dots - Small Yellow
precache_model (PART_DOTSML_GOLD); // Dots - Small Gold
precache_model (PART_BUBBLE_RED); // Bubbles - Red
precache_model (PART_DOTMED_RED); // Dots - Medium Red
precache_model (PART_DOTSML_RED); // Dots - Small Red
precache_model (PART_DOTMED_GREEN); // Dots - Medium Green
precache_model (PART_DOTSML_GREEN); // Dots - Small Green
precache_model (PART_DOTMED_LGREEN); // Dots - Medium Light Green
precache_model (PART_DOTSML_LGREEN); // Dots - Small Light Green
precache_model (PART_DOTSML_PURP); // Dots - Purple/Pink
precache_model (PART_DOTMED_PURP); // Dots - Purple/Pink
precache_model (PART_BUBBLE_WHITE); // Bubbles - White
precache_model (PART_DOTSML_WHITE); // Dots - Small White
precache_model (PART_DOTMED_GREY); // Dots - Medium Grey
precache_model (PART_DOTSML_GREY); // Dots - Small Grey
};