Forum

Scratch QC Water Bug??

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

Scratch QC Water Bug??

Postby drm_wayne » Sun May 19, 2013 2:38 pm

Hey,

Im currently experimenting with the Scratch QC and i noticed that there is a bug with the water handling:
When the player comes out of the water GOD mode gets turned ON and notarget too...
Is there a way to fix it ?? It happends in DP, Fitzquake and DQuake.
User avatar
drm_wayne
 
Posts: 232
Joined: Sat Feb 11, 2012 5:47 pm

Re: Scratch QC Water Bug??

Postby r00k » Mon May 20, 2013 3:54 pm

id assume its a QuakeC bug, maybe an overloaded bit? FL_INWATER or something.

Code: Select all
float   FL_FLY                                  = 1;
float   FL_SWIM                                 = 2;
float   FL_CLIENT                               = 8;    // set for all client edicts
float   FL_INWATER                              = 16;   // for enter / leave water splash
float   FL_MONSTER                              = 32;
float   FL_GODMODE                              = 64;   // player cheat
float   FL_NOTARGET                             = 128;  // player cheat
float   FL_ITEM                                 = 256;  // extra wide size for bonus items
float   FL_ONGROUND                             = 512;  // standing on something


Can you point to the tutorial you are using?

Here's the watermove code i use in one of my projects
Code: Select all
void() WaterMove =
{
   if (!self.waterlevel)
   {
      sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM);
      self.flags = self.flags - (self.flags & (FL_INWATER | FL_WATERJUMP));   // R00k: added FL_WATERJUMP here.
      self.waterlag = 0;
      return;
   }

   if (self.movetype == MOVETYPE_NOCLIP)
      return;

   if (self.health < 0)      
      return;

   if (!(self.flags & FL_INWATER))
   {
      // player enter water sound
      if (self.watertype == CONTENT_LAVA)
         sound (self, CHAN_BODY, "player/inlava.wav", 1, ATTN_NORM);
      else if (self.watertype == CONTENT_WATER)
         sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM);
      else if (self.watertype == CONTENT_SLIME)
         sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM);
      self.flags = self.flags | FL_INWATER;
      self.dmgtime = 0;
      self.air_finished = time + 12;
      //r00k sink delay after initial splash      
      //this fixes that bug while holding jump key and landing on water      
      self.waterlag = (time + 0.2);
   }

   if (self.waterlevel != 3)
   {
      if (self.air_finished < time)
         sound (self, CHAN_VOICE, "player/gasp2.wav", 1, ATTN_NORM);
      else
      {
         if (self.air_finished < time + 9)
            sound (self, CHAN_VOICE, "player/gasp1.wav", 1, ATTN_NORM);
      }
      self.air_finished = time + 12;
      self.dmg = 2;
   }
   else
   {
      if (self.air_finished < time)
      {   
         if (self.pain_finished < time)
         {
            self.dmg = self.dmg + 2;
            
            if (self.dmg > 5)
               self.dmg = 2;
            
            self.deathtype = "drowning";   // 1998-08-12 optional: Drowning doesn't hurt armor by Maddes/Athos
            
            T_Damage (self, world, world, self.dmg);
            
            self.pain_finished = time + 1;
         }
      }
      else
      {
         if ((boss.state == CA_MATCH_ROUNDSTART) && (self.waterlevel == 3))
         {            
            if (self.air_finished < time + 8)//dont spam every frame, just once every 8 seconds. (R00k: 1.97:[9/25/2012:12:04PM])
               self.air_finished = time + 12;
         }
      }
   }
   
   if ((self.watertype == CONTENT_LAVA))
   {   // do damage
      if (self.dmgtime < time)
      {
         if (self.radsuit_finished > time)
         self.dmgtime = time + 1;
         else
         self.dmgtime = time + 0.2;

         T_Damage (self, world, world, 10*self.waterlevel);
      }
   }
   else if ((self.watertype == CONTENT_SLIME))
   {   // do damage
      if (self.dmgtime < time && self.radsuit_finished < time)
      {
         self.dmgtime = time + 1;
         T_Damage (self, world, world, 4*self.waterlevel);
      }
   }

   if (!(self.flags & FL_WATERJUMP))
   {      
      self.velocity = self.velocity - 0.8*self.waterlevel*frametime*self.velocity;
   }
   
   if ((self.waterlevel == 2))
   {
      CheckWaterJump ();
   }
};
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Re: Scratch QC Water Bug??

Postby drm_wayne » Mon May 20, 2013 4:45 pm

Its this one:

http://sourceforge.net/projects/qcfs/files/qcfs/0.1/QCFS-0.1.zip/download

(be carefull, dont extract that alexqcc.exe)

And for unkown reasons it turns on GOD mode and sometimes NOTARGET too :/
User avatar
drm_wayne
 
Posts: 232
Joined: Sat Feb 11, 2012 5:47 pm

Re: Scratch QC Water Bug??

Postby r00k » Mon May 20, 2013 8:07 pm

i cant even download that file. Microsoft Security Essentials basically erases it after i download it; because it finds a "threat" in that .exe. :|

post JUST the watermove code?
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Re: Scratch QC Water Bug??

Postby drm_wayne » Mon May 20, 2013 10:09 pm

sure, here:

Code: Select all
/*
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
WaterMove

Can be used for clients or monsters
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
*/
void() WaterMove =
{
    if (self.movetype == #MOVETYPE_NOCLIP)
        return;
    if (self.health < 0)
        return;

    if (self.waterlevel != 3)
    {
        self.air_finished = time + 12;
        self.dmg = 2;
    }
    else if (self.air_finished < time && self.pain_finished < time)
    {   // drown!
        self.dmg = self.dmg + 2;
        if (self.dmg > 15)
            self.dmg = 10;
        T_Damage (self, world, world, self.dmg);
        self.pain_finished = time + 1;
    }

    if (self.watertype == #CONTENT_LAVA && self.dmgtime < time)
    {   // do damage
        self.dmgtime = time + 0.2;
        T_Damage (self, world, world, 6*self.waterlevel);
    }
    else if (self.watertype == #CONTENT_SLIME && self.dmgtime < time)
    {   // do damage
        self.dmgtime = time + 1;
        T_Damage (self, world, world, 4*self.waterlevel);
    }

   if (!self.waterlevel)
   {
      if (self.flags & #FL_INWATER)
      {
      // player leave water sound
         sound (self, #CHAN_BODY, "misc/outwater.wav", 1, #ATTN_NORM);
         self.flags = self.flags - #FL_INWATER;
      }
      return;
   } else {
      self.flags = self.flags + #FL_INWATER;
      self.dmgtime = 0;
   }
};


User avatar
drm_wayne
 
Posts: 232
Joined: Sat Feb 11, 2012 5:47 pm

Re: Scratch QC Water Bug??

Postby r00k » Mon May 20, 2013 10:41 pm

ok not sure what the # is in front the bitflags but
at the end, it has self.flags = self.flags + FL_INWATER
thats the bug. its just adding 16 to self.flags everytime you go out of the water.
Which can push self.flags to equal 64 (FL_GODMAODE) and later to 128 (FL_NOTARGET)

when i want to add to a bitfield to a value i like to use |,
like
Code: Select all
self.flags = (self.flags | FL_INWATER);

and to subtract
Code: Select all
self.flags = self.flags - (self.flags & FL_INWATER);


this will add or subtract the given value from the TOTAL value of the variable.
i know sometimes in the original code idsoftware has flag = flag - value
but imho this is wrong and ive changed this to avoid bugs...

anyone else can correct me on this but this is just how i view dealing with bitwise operations in standard QuakeC..
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Re: Scratch QC Water Bug??

Postby frag.machine » Tue May 21, 2013 2:11 am

It *IS* wrong.

The safe way to erase a flag is:

Code: Select all
self.flags = self.flags - (self.flags & FL_BLAH);


If you blindly subtract a value from self.flags, you end up messing all the bits (FL_GOD, FL_NOTARGET, etc).
The code above only clears something from self.flags if already set, otherwise it's unchanged.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
User avatar
frag.machine
 
Posts: 2090
Joined: Sat Nov 25, 2006 1:49 pm

Re: Scratch QC Water Bug??

Postby Spike » Tue May 21, 2013 11:36 am

standard/traditional notation:
to set: self.flags = self.flags | FL_BLAH;
to clear: self.flags = self.flags - (self.flags & FL_BLAH);

hexenc notation (works with fteqcc):
to set: self.flags (+) FL_BLAH;
to clear: self.flags (-) FL_BLAH;

more c-like notation (works with fteqcc):
to set: self.flags |= FL_BLAH;
to clear: self.flags &~= FL_BLAH;

As a general rule, you should never directly add nor subtract bitflags, for consistancy you should keep such logic using bitwise operations as it means you're less likely to end up using non-bitwise-safe operations on them, and its easier to see such unsafe operations. The exception to this rule is that QC does not support bit-wise not, thus with standard qc you don't have a choice but to subtract a masked copy of the value (the other notations internally do the same).
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: Scratch QC Water Bug??

Postby drm_wayne » Wed May 22, 2013 1:46 pm

It was indeed wrong in the ScratchQC, i wonder why the creattor never noticed it xD :o
User avatar
drm_wayne
 
Posts: 232
Joined: Sat Feb 11, 2012 5:47 pm


Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest