Announcement

Collapse
No announcement yet.

imposters

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • imposters

    How would I use QC to make one monster turn into another upon "waking up"?

  • #2
    setmodel
    www.quakeone.com/qrack | www.quakeone.com/cax| http://en.twitch.tv/sputnikutah

    Comment


    • #3
      r00k has it right. But if you want it to use the right animations, etc. you'll need to use a bit more code. But for an easy quick hack solution to see it in game real quick I'll give you a quick tut. Free of charge. Ok first lets open up ai.qc. Scroll down to FindTarget (). It looks like this:


      Code:
      float() FindTarget =
      {
      	local entity	client;
      	local float		r;
      
      // if the first spawnflag bit is set, the monster will only wake up on
      // really seeing the player, not another monster getting angry
      
      // spawnflags & 3 is a big hack, because zombie crucified used the first
      // spawn flag prior to the ambush flag, and I forgot about it, so the second
      // spawn flag works as well
      	if (sight_entity_time >= time - 0.1 && !(self.spawnflags & 3) )
      	{
      		client = sight_entity;
      		if (client.enemy == self.enemy)
      			return TRUE;
      	}
      	else
      	{
      		client = checkclient ();
      		if (!client)
      			return FALSE;	// current check entity isn't in PVS
      	}
      
      	if (client == self.enemy)
      		return FALSE;
      
      	if (client.flags & FL_NOTARGET)
      		return FALSE;
      
      	if (client.items & IT_INVISIBILITY)
      		return FALSE;
      
      	r = range (client);
      	if (r == RANGE_FAR)
      		return FALSE;
      		
      	if (!visible (client))
      		return FALSE;
      
      	if (r == RANGE_NEAR)
      	{
      		if (client.show_hostile < time && !infront (client))
      			return FALSE;
      	}
      
      	else if (r == RANGE_MID)
      	{
      		if ( /* client.show_hostile < time || */ !infront (client))
      			return FALSE;
      	}
      	
      //
      // got one
      //
      	self.enemy = client;
      	if (self.enemy.classname != "player")
      	{
      		self.enemy = self.enemy.enemy;
      		if (self.enemy.classname != "player")
      		{
      			self.enemy = world;
      			return FALSE;
      		}
      	}
      	
      	FoundTarget ();
      
      	return TRUE;
      };


      Scrolls down to the end of FindTarget (). So this routine looks for an enemy and if an enemy is spotted it will run the FoundTarget routine as you can see on the bottom. So just before FoundTarget is run we want to go ahead and change our imposter to his true FORM! In this case we will disguise enforcers as grunts! Those sneaky bastards! In order to simplify this transition we are just going to use the routine created in enforcer.qc at the very bottom. Why? Well if we just simply setmodel here it will continue to use the same sounds and animations as the grunt. We don't want that because we know he is really the big bad sneaky ENFORCER!! We must expose him! But we also want him to use his own animations and sounds

      To do this is very easy. We will just hack it in. So instead of setting up precaching sound, setmodel, self.th_stand, etc, etc we can just run the nice little routine called monster_enforcer. This little routine will do all that work for us and then some. So lets stick it right before FoundTarget ().

      Code:
      //
      // got one
      //
      	self.enemy = client;
      	if (self.enemy.classname != "player")
      	{
      		self.enemy = self.enemy.enemy;
      		if (self.enemy.classname != "player")
      		{
      			self.enemy = world;
      			return FALSE;
      		}
      	}
      	
      	[COLOR="Lime"]if(self.classname == "monster_army")
      	monster_enforcer();[/COLOR]
      	
      	
      	FoundTarget ();
      
      	return TRUE;
      };
      As you can see in the green highlight that is all we need in this routine. What does it do? Well in a nutshell it says if the monster is a grunt, then we need to change him to an enforcer when he see's an enemy (you). Then after that the FoundTarget runs and he will attack! That's pretty much it except for one little detail. Monster_enforcer routine gets defined much later in the compile process so we will need to declare it here in ai.qc to keep the compiler happy. So go to the top of ai.qc and place this:


      Code:
      */
      [COLOR="lime"]void() monster_enforcer;[/COLOR]  [COLOR="Yellow"]//Just add this here! [/COLOR]
      void() movetarget_f;
      void() t_movetarget;
      void() knight_walk1;
      void() knight_bow6;
      void() knight_bow1;
      That will do it. Compile and you're done. Go to e1m1 and find a grunt. When he sees you he will be exposed as the ENFORCER! Now there are some changes that can be made to make this work much better, etc. But this is a quick and dirty way to get this running in say under 5 minutes? You may get some weird behavior with certain monsters but like I said this is just a hack version. It can easily be improved Have fun! Note: This can created a bit of lag if you have many grunts detect you all at once.
      Last edited by PrimalLove; 09-17-2014, 01:59 AM.

      Comment


      • #4
        Thanks for answering. I wound up making an imposter flag that can be set in QuakeEd. If the imposter flag is set, more or less what you said to do happens regarding the value of the flag. I gave you rep for exposing the general idea. I also took rep from R00k for not being helpful at all.

        Comment


        • #5
          Ah yes, spawn flags are a great way to do this.

          Comment


          • #6
            Well that's fine Cigan. My post it was 1:12am. I was heading off to bed.
            Your post was your first here and kinda minimal, so i gave you a minimal answer.
            www.quakeone.com/qrack | www.quakeone.com/cax| http://en.twitch.tv/sputnikutah

            Comment


            • #7
              @r00k LOL! No one should necessarily expect complete answers and even if you don't get them its probably not a good reason to "take" rep from someone. (I wasn't aware you could take it?) r00k did provide an answer just not a thorough one. Doesn't mean he wasn't helpful. It's probably a better idea to just not rep someone than to take rep because you weren't satisfied with the answer provided. I don't believe r00k was rude as all he said was setmodel which technically is right. Also, Cigan, you didn't provide a thorough question so I made many assumptions on my part. Better answers come from more thorough questions. Just my two cents.
              Last edited by PrimalLove; 09-17-2014, 10:14 AM.

              Comment


              • #8
                watch out Cigan cracks the whip
                [ame=http://www.youtube.com/watch?v=AYURxfaTdpY]Bender Remember Me - S3E17 A Pharaoh to Remember - YouTube[/ame]
                Want to get into playing Quake again? Click here for the Multiplayer-Startup kit! laissez bon temps rouler!

                Comment


                • #9
                  R00k is a legendary coder. He didn't get that way by asking vague questions and expecting detailed tutorials in QC. When someone like R00k or Spike gives you a quick one word answer, that is your cue to start doing your homework and researching that answer. Nobody owes you an explanation for anything, you're a new arrival in a friendly forum where people who have been here and dealt with rookies like you and I for several years still answer basic questions. You should be grateful, instead you're looking a gift horse in the mouth.

                  Additionally, you likely just burned one of the biggest bridges you had when it comes to QC help.

                  I suppose I'll be getting bad rep now too, but I always call it like I see it.
                  'Replacement Player Models' Project

                  Comment


                  • #10
                    @PrimalLove: My question was perfect and so was your answer. I wanted to know how create an imposter that exposes itself upon seeing the player. You understood that animarions would need to be considered and took the obvious route that I want one enemy to turn into a working version of another. setmodel is neither right or an answer. It's a troll answer to a question that concisely asked exactly what I wanted to do.

                    Comment


                    • #11
                      primal's answer was hardly perfect. its wasteful, excessive, and buggy. it fails to precache things, will potentially allow walking monsters to get stuck in walls, and will bug out monster counters.
                      and the key part that changes the appearance of your monster? a setmodel call! yup! its just hidden behind all the extra stuff that his method involves.

                      setmodel is _EXACTLY_ the correct solution. set up some fake idle animation or something for it to use, and then when you switch to one of the other ai states, call setmodel to switch the model when you switch the animation.
                      its simple and less invasive, all the special logic is confined to only your new monster's code.

                      >I wanted to know how create an imposter that exposes itself upon seeing the player
                      lol, that just makes it sound like you want to make a sex pest.
                      that might be funny of course. hurrah for quake's lack of realism.
                      Some Game Thing

                      Comment


                      • #12
                        @Spike

                        I did say my solution was a "hack" and would just simply get it going in less than 5 minutes. But it does in fact precache, just not ideally. It was just a quick and dirty as described in my post. I also made mention that it could be done much better with proper code. Also I mentioned some of the limitations with monsters bugging out. Maybe you didn't read my post? :/ But you can't simply use setmodel and a idle animation. You have to set the th_walk, th_run, etc so that it uses all the right animations. As it will use everything from the entity that was spawned in the first place (the grunt). So my solution tho very much a hack does actually do everything it technically needs to work. Oh, and it does it in less than 5 minutes of code. MUHAHAHAH!
                        Last edited by PrimalLove; 09-17-2014, 12:34 PM.

                        Comment


                        • #13
                          precaches mid-game are not exactly precaches, and will crash-to-console on anything other than dp+fte.
                          by invoking the spawn function mid-game, you're bumping total_monsters again, which can bug out coop games in obscure ways.
                          by using the monster's spawn function like that, you're also imposing weird delays while the monster thinks through its various spawn functions. at the end of that, it'll have forgotten who it was angry with, and you'll have to annoy it again.

                          the way I see it, the monster that you actually fight would need to be new in some way for the whole thing to actually make any sense.
                          a new idle function (which starts with a setmodel to its fake form), with a setmodel in the (presumed existing) th_run/th_walk functions to revert it to its 'true' form should really be all that's needed for it.
                          Some Game Thing

                          Comment


                          • #14
                            @Spike

                            I agree.

                            Comment


                            • #15
                              i have played with code once to turn players into zombies but had to create an entire new monster that synched animations to player input; like throwing gibs when they fired etc.
                              in that little zombie mod i made last october i had zombies spawn when grunts
                              were gibbed which looked like the grunt was shedding an outter layer of skin that revealed an inner flesh and bone that would attack you.
                              i cant remember all the details off the top of my head atm but something like this cod work for imposters just remove the grunt toss out a particle effect and spawn a new one. but ya it would really thow off the monster count on the scoreboard. ill try to make a better qc example when i get home.
                              www.quakeone.com/qrack | www.quakeone.com/cax| http://en.twitch.tv/sputnikutah

                              Comment

                              Working...
                              X