Inside3D!
     

Decal-Management-System...how to get it working

 
Post new topic   Reply to topic    Inside3d Forums Forum Index -> QuakeC Programming
View previous topic :: View next topic  
Author Message
skite2001



Joined: 17 Nov 2008
Posts: 17

PostPosted: Wed Nov 26, 2008 6:26 pm    Post subject: Decal-Management-System...how to get it working Reply with quote

Hello guys,
maybe everybody knows the problem with decal staytime, for example bulletholes, wallnails, shells.
The normal procedure would be something like:

Quote:
Code:

newmis.nextthink = time + 10 //remain 10 sec...
newmis.think = SUB_Remove //...then get removed


it looks really funny, if you got working wallnails, shoot em at a wall and after 10 sec it looks like "domino day"

after some checking of LordHavocs DP mod qc files i found something interesting:

he set a variable for maxdetails..lets say 1000 decals, that stay almost the whole time and don't get removed. After the 1001th decal, the oldest decors got removed each frame, to maintain a certain maximum decors (1000 for example).

i really like this idea and want to add this "feature" to my mod,
but it seems it isn't working, or i'm doing something wrong -.-*
I'm good at copy&paste and minor fixing, but i'm not a "got-no-live-quakec-coder" ^_-

here's the code i got:
Quote:
Code:

void(entity e) removedecor =
{
   if (e.classname != "decor")
   {
      // if this is not a decor, just make it invisible
      e.model = "";
      return;
   }
   numdecors = numdecors - 1;
   remove(e);
};

entity(entity e) newdecor =
{
   if (e == world)
   {
      e = spawn();
      e.classname = "decor";
   }
   if (e.classname == "decor")
      numdecors = numdecors + 1;
   // set up common defaults
   e.isdecor = TRUE;
   //e.createdtime = time;
   e.cnt = 10 * (0.5 + random());
   e.alpha = 1;
   e.effects = EF_LOWPRECISION;
   e.flags = e.flags - (e.flags & FL_ONGROUND);
   e.groundentity = world;
   e.movetype = MOVETYPE_NONE;
   e.solid = SOLID_NOT;
   e.frame = 0;
   e.havocattack = FALSE;
   e.touch = SUB_Null;
   return e;
};

//.float createdtime;

// removes the oldest decors each frame to maintain a certain maximum decors
void() decorframe =
{
   local entity estart, e;
   local float decay;
   //local entity b1, b2, b3, b4, b5, b6, b7, b8, b9, b10;
   //local float bt1, bt2, bt3, bt4, bt5, bt6, bt7, bt8, bt9, bt10, iterations;

   // different number of decors in multi-player (to avoid lag on modems)
   if (maxclients > 1)
      maxdecors = 32;
   else if (cvar("spawnmonsters"))
      maxdecors = 500;
   else
      maxdecors = 10000;
   if (cvar("ekg"))
      maxdecors = maxdecors * 5;
   // overridable by saved2 cvar on server console
   if (cvar("decors"))
      maxdecors = cvar("decors");
   maxdecors = bound(1, maxdecors, 16384);

   // numdecors is allowed to be bogus as long as it is >= the real number of decors
   // (but perfection is clearly preferable)
   if (numdecors <= maxdecors)
      return;

   // recount all the decors
   numdecors = 0;
   estart = e = findchain(classname, "decor");
   while(e)
   {
      numdecors = numdecors + 1;
      e = e.chain;
   }
   if (numdecors <= maxdecors)
      return; // nothing to do

   // changed decor removal policy to simply make them have timeouts that only apply when the decor limit has been reached
   // the timeout rate depends on how far over the limit it is, so this does adapt to sudden excess
   decay = frametime * (numdecors / maxdecors);
   e = estart;
   while(e)
   {
      if (e.cnt > 0)
         e.cnt = e.cnt - decay;
      else
         removedecor(e);
      e = e.chain;
   }
};

// used for various little bouncing debris to avoid getting stuck in the air
void() DecorThink =
{
   self.nextthink = time;
   self.flags = self.flags - (self.flags & FL_ONGROUND);
   if (pointcontents(self.origin) == CONTENT_SOLID)
      removedecor(self);
};


void(vector org, entity en, vector dir, string dmodel, float dskin, float dframe, float importance, float ismodel) newdecal =
{
   local vector dirangles;
   local entity e;
   if (cvar("temp1") & 2048)
      return;
   if (en.solid != SOLID_BSP || en.model == "")
      return;
   dir = normalize(dir);
   org = org + dir; // push it off the surface
   // to orient the bullet hole properly
   if (ismodel)
      dirangles = vectoangles(dir); // sprite bug
   else if (!ismodel)
   {
      dirangles = vectoangles('0 0 0' - dir); // sprite bug
      dirangles_x = 0 - dirangles_x; // sprite bug
   }

   e = findchain(classname, "decor");
   while (e != world)
   {
      if (e.angles == dirangles) // same surface
      if (e.model == dmodel) // same type of decal
      if (vlen(e.origin - org) < 4) // remove existing mark
         remove(e);
      e = e.chain;
   }

   if (importance >= 1000) // permanent
   {
      e = spawn();
      e.classname = "permanentdecal";
   }
   else
   {
      // if in danger of running out of entities, don't spawn any new ones
      if (numdecors >= 16384)
         return;
      e = newdecor(world);
      e.cnt = importance * (0.5 + random());
   }
   e.skin = dskin;
   e.frame = dframe;
   e.angles = dirangles;
   setmodel (e, dmodel);
   setsize (e, '0 0 0', '0 0 0');
   setorigin (e, org);
   if (en != world) // might be a mobile surface, follow it
   {
      e.aiment = en;
      e.view_ofs = org - en.origin;
      e.punchangle = en.angles; // base angles
      e.v_angle = e.angles - en.angles;
      e.movetype = MOVETYPE_FOLLOW;
   }
};


how can i add this to a shotgun shell script?
Quote:
Code:

float() crandom;
void() shell_touch;

/*
===============
eject_shell

Spews a spent shell casing from a shotgun
===============
*/
void(vector org,vector dir, float punch, vector spread) eject_shell =
{
        local float     flip;
   local vector transform;
        // Spawn one shell
   newmis = spawn ();
   newmis.owner = self;
        newmis.movetype = MOVETYPE_BOUNCE;
   newmis.solid = SOLID_BBOX;

   newmis.angles = vectoangles(dir);

        newmis.touch = shell_touch;
        newmis.classname = "shellcasing";
   newmis.think = SUB_Remove;
        newmis.nextthink = time + 20;
        setmodel (newmis, "progs/shelcase.mdl");
   setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
   setorigin (newmis, org);

        // pick a random numbers
   flip = crandom();
   spread_x = spread_x * flip;
   flip = crandom();
   spread_y = spread_y * flip;
   flip = crandom();
   spread_z = spread_z * flip;

      transform_x = dir_y + spread_x;
   transform_y = 0 - dir_x + spread_y;
   transform_z = dir_z + spread_z; 
        newmis.velocity = transform*punch;

        // pick a random number
        flip = random();

        // based on that rate, pick a rate at which to spin
        if (flip < 0.25)
        newmis.avelocity = '300 300 300';

        else if (flip < 0.5)
        newmis.avelocity = '150 300 100';

        else if (flip < 0.75)
        newmis.avelocity = '200 100 0';

        else
        newmis.avelocity = '400 200 100';
};

void() shell_touch =
{
     // DO NOT play the sound if we hit a door.
     if (other.classname == "door")
        return;

     sound (self, CHAN_WEAPON, "weapons/shellhit.wav", 1, ATTN_NORM);
};


help would be really appreciated!
thx and regrats
~skitey
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Inside3d Forums Forum Index -> QuakeC Programming All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2004 phpBB Group