Forum

More thoughts/questions re: lightning

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

More thoughts/questions re: lightning

Postby ajay » Sun May 09, 2010 5:44 pm

Thanks to this thread: viewtopic.php?t=2258 and especially Dr Shadowborg, I have working lightning effect, that so far, is partially controllable by a map trigger. The code (DrS's not mine) is quote at the bottom of this post.

Firstly I should state what exactly I'm after:
- a lightning bolt, with a constant stream, running for approx 10 seconds
- it should be triggerable, not by a map trigger, but by a variable reaching a certain point, e.g:
if (abc == 5)
event_lightningbars();
- after finishing it should then be re-triggerable (great english eh?) by the variable again reaching that certain point ("abc" would be reset in between)

My concerns:
- I've always been useless at time related coding, so have little clue where in the code below to stick the 'work for 10 seconds and then stop' bit, and, indeed, what it should be
- would the:
if (abc == 5)
event_lightningbars();
actually work? and if so, where would I put it? pre-physics, post. I'm always cocking it up by putting it in the wrong place

Thanks for anyone able to unpick my ramblings, it's been a long day.... :)

void () lightningbars_use = {

if ( !self.state )
self.state = 1;
else
self.state = 0;

};

void () lightningbars_think = {

self.think = lightningbars_think;
self.nextthink = time + self.wait;

if(self.state == 0)//
return;


self.ltime = time + 0.25;

if ( self.noise )
{
sound(self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
}

// Only show particles if client is visible.
// This helps to keep network traffic down to a minimum.
// if (!checkclient() )
// return;

if(!self.enemy)
{
self.enemy = find (world, targetname, self.target);
if (!self.enemy)
objerror ("couldn't find target");
}
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
WriteEntity (MSG_BROADCAST, self);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
WriteCoord (MSG_BROADCAST, self.enemy.origin_x);
WriteCoord (MSG_BROADCAST, self.enemy.origin_y);
WriteCoord (MSG_BROADCAST, self.enemy.origin_z);
};

/*QUAKED event_lightningbars (0 .5 .8) ?
Creates a lightining bolt between itself, and it's target.

"target" is the targetted object for the endpoint.
"targetname" is the name for toggling it.
"wait" is the amount of time between flashes. default 1.
*/

void() event_lightningbars =
{
if(!self.wait)
self.wait = 0;// eQ addition, to make constant stream

self.classname = "lightningbars";
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_NONE;
self.model = string_null;

if ( self.noise )
{
precache_sound( self.noise );
}
self.ltime = time;

self.think = lightningbars_think;

self.nextthink = time + 3; // so that it has time to load the map
self.use = lightningbars_use;
};
User avatar
ajay
 
Posts: 559
Joined: Fri Oct 29, 2004 6:44 am
Location: Swindon, UK

Postby ajay » Thu May 13, 2010 8:52 am

Bumped, 'cos I'm needy like that ;)
User avatar
ajay
 
Posts: 559
Joined: Fri Oct 29, 2004 6:44 am
Location: Swindon, UK

Postby frag.machine » Thu May 13, 2010 12:33 pm

From the top of my head (untested, so it's very likely to have some overlooked error on it):

Code: Select all
// WARNING: this will spam lots of TE_LIGHTNING1 messages!
void() lightning_bar_think =
{
  if (self.button0 != 0)
  {
    self.wait = time + 10;
    self.button0 = 0;
  }
 
  if (self.wait > time)
  {
    if ( self.noise )
    {
      sound(self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
    }

    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
    WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
    WriteEntity (MSG_BROADCAST, self);
    WriteCoord (MSG_BROADCAST, self.origin_x);
    WriteCoord (MSG_BROADCAST, self.origin_y);
    WriteCoord (MSG_BROADCAST, self.origin_z);
    WriteCoord (MSG_BROADCAST, self.enemy.origin_x);
    WriteCoord (MSG_BROADCAST, self.enemy.origin_y);
    WriteCoord (MSG_BROADCAST, self.enemy.origin_z);
  }
 
  self.think = lightning_bar_think;
  self.nextthink = time + 0.25;
};

void() lightning_bar_use =
{
  self.button0 = 1;
};

func_lightning_bar =
{
  self.enemy = find (world, targetname, self.target);
  if (!self.enemy) 
  {
    objerror ("couldn't find target");
    remove (self);
    return;
  }

  self.use = lightning_bar_use;
  self.think = lightning_bar_think;
  self.nextthink = time + 0.25;
};


With this code you should be able to either trigger the lightning by using the entity, or directly setting self.button0.
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

Postby Dr. Shadowborg » Thu May 13, 2010 3:01 pm

ajay wrote:Bumped, 'cos I'm needy like that ;)


I can modify that for you, but I need more information:

1. Is abc a global or is it entity assigned? i.e. self.abc
OR
2. Is what you want a multi-trigger thingie that does a "2 more to go...", then fire off lightning for x number of seconds after which reset style?
User avatar
Dr. Shadowborg
InsideQC Staff
 
Posts: 1110
Joined: Sat Oct 16, 2004 3:34 pm

Postby ajay » Thu May 13, 2010 3:25 pm

Thanks both of you. For clarification 'abc' may be a number of things; number of enemies killed*, or number of items collected or number of other objectives achieved, depending on the gameplay for the level or part of the level.
*for the purpose of this piece of code, assume it's enemies killed, however abc would be calculated independently from the normal enemies killed total.
Basically it needs to be triggered by the player completing some kind of task/s, not by a brush trigger placed in the map
User avatar
ajay
 
Posts: 559
Joined: Fri Oct 29, 2004 6:44 am
Location: Swindon, UK

Postby frag.machine » Thu May 13, 2010 5:40 pm

In my code, replace all occurrences of "self.button0" by your preferred variable name and everything should still work OK.
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: More thoughts/questions re: lightning

Postby Dr. Shadowborg » Sat May 15, 2010 7:41 pm

Okay here's what you do:

First, make a global float in your defs.qc or wherever called worldgoal_complete. (replace with whatever floats your boat)

Next replace lightningbars code with the following:

Code: Select all
void () lightningbars_use = {

   if ( !self.state )
       self.state = 1;
     else
       self.state = 0;

};

void () lightningbars_think = {

   self.think = lightningbars_think;
   self.nextthink = time + self.wait;

  // Check to see if it's a goal fired type or not and if so, tell it to fire and for how long to fire.
  if(self.ammo_shells)
   {
    if(self.ammo_shells && worldgoal_complete == self.ammo_shells)
    {
     self.attack_finished = time + self.delay;
     self.state = TRUE;
     
      // we need to turn it off again, so for the purposes of this example, I'm resetting worldgoal_complete to 0.  Adjust code for your use accordingly.
     worldgoal_complete = 0;
    }
   // Turn it off if duration has passed.
   if(self.attack_finished <= time)
    self.state = 0;
  }

   if(self.state == 0)
     return;

   self.ltime = time + 0.25;

   if ( self.noise )
      {
      sound(self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
      }

   // Only show particles if client is visible.
   // This helps to keep network traffic down to a minimum.
//   if (!checkclient() )
//      return;

     if(!self.enemy)
      {
        self.enemy = find (world, targetname, self.target);
        if (!self.enemy)
        objerror ("couldn't find target");
      }
        WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
        WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
        WriteEntity (MSG_BROADCAST, self);
        WriteCoord (MSG_BROADCAST, self.origin_x);
        WriteCoord (MSG_BROADCAST, self.origin_y);
        WriteCoord (MSG_BROADCAST, self.origin_z);
        WriteCoord (MSG_BROADCAST, self.enemy.origin_x);
        WriteCoord (MSG_BROADCAST, self.enemy.origin_y);
        WriteCoord (MSG_BROADCAST, self.enemy.origin_z);
};

/*QUAKED event_lightningbars (0 .5 .8) ?
Creates a lightining bolt between itself, and it's target.

"target" is the targetted object for the endpoint.
"targetname" is the name for toggling it.
"wait" is the amount of time between flashes.  default 1.
*/

void() event_lightningbars =
{
   if(!self.wait)
    self.wait = 0;// eQ addition, to make constant stream

   self.classname = "lightningbars";
   self.solid = SOLID_NOT;
   self.movetype = MOVETYPE_NONE;
   self.model = string_null;

   if ( self.noise )
      {
      precache_sound( self.noise );
      }
   self.ltime = time;

  self.think = lightningbars_think;

 self.nextthink = time + 3; // so that it has time to load the map
 self.use = lightningbars_use;
};


Make note of the changes to lightningbars_think, because you may have to modify it for worldgoal_complete control stuffs, and whatnot.

Also note that you will need to set the .ammo_shells field for matching the firing of the event_lightningbars to worldgoal_complete, also that the .delay field will set how long the bolt will fire.

I haven't actually tested this yet, no time to do so, but I think this should work. Let me know how it goes.
User avatar
Dr. Shadowborg
InsideQC Staff
 
Posts: 1110
Joined: Sat Oct 16, 2004 3:34 pm

Postby ajay » Tue May 18, 2010 8:27 pm

Thanks so much for you help. I've tinkered a little with your code and now, after a test piece of gameplay is achieved, the lightning fires, and then, after a set bit of time, turns off. Which is bloody great.
The only problem is that I've been trying to get 6 to fire at once, and only one does, but it's only fair I have to solve a little of this myself!
Thanks again.
User avatar
ajay
 
Posts: 559
Joined: Fri Oct 29, 2004 6:44 am
Location: Swindon, UK

Postby ajay » Wed May 19, 2010 7:01 pm

Solved it! Thanks again by the way.
User avatar
ajay
 
Posts: 559
Joined: Fri Oct 29, 2004 6:44 am
Location: Swindon, UK

Postby Dr. Shadowborg » Fri May 21, 2010 3:32 am

No problem, was gone yesterday just came back in today.

Your welcome, and glad you got it working! :D

Feel free to ask again if you ever need any more help. :wink:
User avatar
Dr. Shadowborg
InsideQC Staff
 
Posts: 1110
Joined: Sat Oct 16, 2004 3:34 pm


Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest