Okay, lets move on. We have created the pcvar variable now, and it points to the cvar, so now the value of the cvar is stored in the pcvar
But wait, there is more in this piece of code. There is a cvar more which is registered!
We register this cvar as a pcvar too, and then use it the same way as in invisible woman.
First the new global variable:
PHP Code:
new gHeroID
new gHasInvis[SH_MAXSLOTS+1]
new gInvisTimer[SH_MAXSLOTS+1]
new gInvisSound[] = "player/heartbeat1.wav"
new pcvarTimer
new pcvarCooldown
Then we register it:
PHP Code:
public plugin_init()
{
register_plugin("SUPERHERO Invis", "1.0", "Jelle")
new pcvarLevel = register_cvar("invis_level", "0")
pcvarTimer = register_cvar("invis_time", "5")
pcvarCooldown = register_cvar("invis_cooldown", "10")
gHeroID = sh_create_hero("Invis", pcvarLevel)
sh_set_hero_info(gHeroID, "Go invis", "Makes you invisible")
sh_set_hero_bind(gHeroID)
}
and now we combine the keydown code using the new pcvars created:
PHP Code:
public sh_hero_key(id, heroID, key)
{
if ( gHeroID != heroID ) return
if ( key == SH_KEYDOWN && is_user_alive(id) )
{
if ( gPlayerUltimateUsed[id] || gInvisTimer[id] > 0 )
{
sh_sound_deny(id)
}
gInvisTimer[id] = get_pcvar_num(pcvarTimer)
if ( get_pcvar_float(pcvarCooldown) > 0.0 )
{
ultimateTimer(id, get_pcvar_float(pcvarCooldown))
}
}
}
Next piece of code in the keydown forward:
PHP Code:
gAlpha = get_cvar_num("inviswoman_alpha")
set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderTransAlpha, gAlpha)
This is where the invisibility is actually set. We know that because of the word alpha, and the use of the native set_user_rendering.
We can see that a new variable has been created to hold the value of the cvar "inviswoman_alpha". First we should create that cvar, and we create it as a pcvar:
PHP Code:
new gHeroID
new gHasInvis[SH_MAXSLOTS+1]
new gInvisTimer[SH_MAXSLOTS+1]
new gInvisSound[] = "player/heartbeat1.wav"
new pcvarTimer
new pcvarCooldown
new pcvarAlpha
PHP Code:
public plugin_init()
{
register_plugin("SUPERHERO Invis", "1.0", "Jelle")
new pcvarLevel = register_cvar("invis_level", "0")
pcvarTimer = register_cvar("invis_time", "5")
pcvarCooldown = register_cvar("invis_cooldown", "10")
pcvarAlpha = register_cvar("invis_alpha", "100")
gHeroID = sh_create_hero("Invis", pcvarLevel)
sh_set_hero_info(gHeroID, "Go invis", "Makes you invisible")
sh_set_hero_bind(gHeroID)
}
Now we have already stored the cvar value in a variable, so we actually do not need to create and use the variable called gAlpha from invisible woman. To retrieve the value of the cvar we use a native called get_pcvar_num, get_pcvar_float or get_pcvar_string as you might have seen. You should already know what a float and a string is. And in case you don't know, num is used for an integer.
So, we can actually combine these two lines into one:
PHP Code:
set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderTransAlpha, get_pcvar_num(pcvarAlpha))
Inserting that into our plugin it becomes:
PHP Code:
public sh_hero_key(id, heroID, key)
{
if ( gHeroID != heroID ) return
if ( key == SH_KEYDOWN && is_user_alive(id) )
{
if ( gPlayerUltimateUsed[id] || gInvisTimer[id] > 0 )
{
sh_sound_deny(id)
}
gInvisTimer[id] = get_pcvar_num(pcvarTimer)
if ( get_pcvar_float(pcvarCooldown) > 0.0 )
{
ultimateTimer(id, get_pcvar_float(pcvarCooldown))
}
set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderTransAlpha, get_pcvar_num(pcvarAlpha))
}
}
Now, what is kRenderFxGlowShell and kRenderTransAlpha? Well, lets look it up!
First we go to check amxmodx.org
here
We see this:
A list of different render modes:
kRenderNormal = 0, /* src */
kRenderTransColor, /* c*a+dest*(1-a) */
kRenderTransTexture, /* src*a+dest*(1-a) */
kRenderGlow, /* src*a+dest -- No Z buffer checks */
kRenderTransAlpha, /* src*srca+dest*(1-srca) */
kRenderTransAdd, /* src*a+dest */
and this:
A list of different render effects:
kRenderFxNone = 0,
kRenderFxPulseSlow,
kRenderFxPulseFast,
kRenderFxPulseSlowWide,
kRenderFxPulseFastWide,
kRenderFxFadeSlow,
kRenderFxFadeFast,
kRenderFxSolidSlow,
kRenderFxSolidFast,
kRenderFxStrobeSlow,
kRenderFxStrobeFast,
kRenderFxStrobeFaster,
kRenderFxFlickerSlow,
kRenderFxFlickerFast,
kRenderFxNoDissipation,
kRenderFxDistort, /* Distort/scale/translate flicker */
kRenderFxHologram, /* kRenderFxDistort + distance fade */
kRenderFxDeadPlayer, /* kRenderAmt is the player index */
kRenderFxExplode, /* Scale up really big! */
kRenderFxGlowShell, /* Glowing Shell */
kRenderFxClampMinScale, /* Keep this sprite from getting very small (SPRITES only!) */
This really didn't help us much, lets dig a bit deeper, we take a look at the include file. We see on amxmodx.org that this native is in the include file called fun.inc, so we take a look at that and search for set_user_rendering, and here is what comes up:
Code:
/* Sets player rendering mode. */
native set_user_rendering(index, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16);
Oh well, this still didn't give us any clue as to what those two is used for, all we know is that it is render modes and render effects. We have seen a few comments as to what the effects and modes are, but we have not seen a complete list. Lets dig deeper. Now I know from reading the comments that these variables is fetched from the amxconst.inc include file. Lets look at that and search for render:
Code:
/* Render for set_user_rendering() */
enum {
kRenderNormal = 0, /* src */
kRenderTransColor, /* c*a+dest*(1-a) */
kRenderTransTexture, /* src*a+dest*(1-a) */
kRenderGlow, /* src*a+dest -- No Z buffer checks */
kRenderTransAlpha, /* src*srca+dest*(1-srca) */
kRenderTransAdd, /* src*a+dest */
};
/* Fx for set_user_rendering() */
enum {
kRenderFxNone = 0,
kRenderFxPulseSlow,
kRenderFxPulseFast,
kRenderFxPulseSlowWide,
kRenderFxPulseFastWide,
kRenderFxFadeSlow,
kRenderFxFadeFast,
kRenderFxSolidSlow,
kRenderFxSolidFast,
kRenderFxStrobeSlow,
kRenderFxStrobeFast,
kRenderFxStrobeFaster,
kRenderFxFlickerSlow,
kRenderFxFlickerFast,
kRenderFxNoDissipation,
kRenderFxDistort, /* Distort/scale/translate flicker */
kRenderFxHologram, /* kRenderFxDistort + distance fade */
kRenderFxDeadPlayer, /* kRenderAmt is the player index */
kRenderFxExplode, /* Scale up really big! */
kRenderFxGlowShell, /* Glowing Shell */
kRenderFxClampMinScale, /* Keep this sprite from getting very small (SPRITES only!) */
};
We still don't know what some of the effects and modes are, and as seen it is quite hard to find out what it does.
Now instead of making a new topic named "What does the effects look like?", you should just test it yourself. I haven't tested it myself, so I really have no idea how it looks like, I have just been using the modes and effects from other plugins since I know how that looks like and I think that's just fine.
So, how can you test this? Well, you can install a 3rd person mode plugin. How do you find that? You DO NOT create a new topic asking for it, you SEARCH for it. Go to the amx mod x section and search in the approved plugins section. Searching for "3rd person" is enough to give me a few results. Then you just try out a few different effects and modes while 3rd person is on and you will be able to see the difference.
Now lets move on with the invisible woman code:
PHP Code:
gInvisWomanMode[id] = true
A new variable has been used here. As seen in the name it is a Boolean which is used to check later on if the person is using the power of not. We might use this later on, so we add it to our code.
First we create the variable:
PHP Code:
new gHeroID
new gHasInvis[SH_MAXSLOTS+1]
new gInvisTimer[SH_MAXSLOTS+1]
new gInvisSound[] = "player/heartbeat1.wav"
new bool:gInvisMode[SH_MAXSLOTS+1]
new pcvarTimer
new pcvarCooldown
new pcvarAlpha
Then we add it to our code:
PHP Code:
public sh_hero_key(id, heroID, key)
{
if ( gHeroID != heroID ) return
if ( key == SH_KEYDOWN && is_user_alive(id) )
{
if ( gPlayerUltimateUsed[id] || gInvisTimer[id] > 0 )
{
sh_sound_deny(id)
}
gInvisTimer[id] = get_pcvar_num(pcvarTimer)
if ( get_pcvar_float(pcvarCooldown) > 0.0 )
{
ultimateTimer(id, get_pcvar_float(pcvarCooldown))
}
set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderTransAlpha, get_pcvar_num(pcvarAlpha))
gInvisMode[id] = true
}
}
Okay, with that done we move on with the next piece of code, still in the keydown forward.
PHP Code:
new message[128]
format(message, 127, "You have now turned invisible")
set_hudmessage(50, 50, 255, -1.0, 0.28, 0, 0.0, 1.0, 0.0, 0.0, 54)
show_hudmessage(id, message)
What is this crap now? Well, we see a new variable called message, so we assume it is a message of some sort. We also see "You have now turned invisible" and as we know this is running when keydown is pressed, so this is to let the user know that he is in fact invisible. We also see a native called show_hudmessage, so we then assume it is a hud message.
A new variable called message is created as an array with 128 blocks. Next is a native used called format. What does format do?
Yes, you guessed it, we are going to look it up!
Searching for format on amxmodx.org
here
It reviles this:
Quote:
Originally Posted by amxmodx.org
format - Format a string with a given format and parameters.
|
Okay, maybe just a bunch of random words to you, so lets dig deeper to see what this does.
Code:
format ( output[], len, const format[], ... )
Okay, first parameter is the output, which is this case is the variable called message, next is the blocks of the array (this native apparently needs an output variable created as an array). As you should know by now, we always minus 1 from the array size. That is because message[0] is 1, message[1] is 2 and so on, and creating a variable like "message[128]" would be 127 in len. The next parameter is what to format. What is formatted in this is "You have now turned invisible".
Basically this makes "You have now turned invisible" in each block of the message variable. This frees you from doing it like this:
PHP Code:
new message[128]
message[0] = "Y"
message[1] = "o"
message[2] = "u"
and so on.
So, next it is setting the hud message, now what does this mean? Yes, we are going to look that up as well!
here
So what we see is that this sets the format for the HUD message.
We also see this:
Code:
set_hudmessage ( red=200, green=100, blue=0, Float:x=-1.0, Float:y=0.35, effects=0, Float:fxtime=6.0, Float:holdtime=12.0, Float:fadeintime=0.1, Float:fadeouttime=0.2, channel=4 )
With this we can set what color the HUD message should have, how long time, where, how and basically everything regarding the HUD message. We also see that each player has 4 channels. This means that a maximum of 4 HUD messages can be written on the screen of a client. This is also why a HUD message might disappear very quick from clients on a server with a lot of HUD messages.
next is show_hudmessage. Looking at the name, this shows the HUD message. First the index to show it to (the guy who pressed the keydown and has the hero) and then the message we wrote.
As the natives are all the same since this hero was made we are going to just use that without an edit of it:
PHP Code:
public sh_hero_key(id, heroID, key)
{
if ( gHeroID != heroID ) return
if ( key == SH_KEYDOWN && is_user_alive(id) )
{
if ( gPlayerUltimateUsed[id] || gInvisTimer[id] > 0 )
{
sh_sound_deny(id)
}
gInvisTimer[id] = get_pcvar_num(pcvarTimer)
if ( get_pcvar_float(pcvarCooldown) > 0.0 )
{
ultimateTimer(id, get_pcvar_float(pcvarCooldown))
}
set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderTransAlpha, get_pcvar_num(pcvarAlpha))
gInvisMode[id] = true
new message[128]
format(message, 127, "You have now turned invisible")
set_hudmessage(50, 50, 255, -1.0, 0.28, 0, 0.0, 1.0, 0.0, 0.0, 54)
show_hudmessage(id, message)
}
}
As a last thing in this keydown forward we see a native called emit_sound:
PHP Code:
emit_sound(id, CHAN_STATIC, gInvisWomanSound, 0.1, ATTN_NORM, 0, PITCH_NORM)
Yes, we are going to look this up too,
here
So, this site says that it, funny enough, emits a sound. The sound HAS to be precached before it can be played. Well, we precached a sound earlier on, and this is where you can use it.
Looking further at amxmodx.org we also see a list of constants used. In invisible woman CHAN_STATIC, ATTN_NORM and PITCH_NORM is used as constants. What else can be used is described on amxmodx.org.
Now, I have always been using this as it is written in invisible woman, so I have no idea how the different constants works, and I am not going to search as deep into it as I did with the render stuff, you will have to do that yourself if you really want to know what it really does.
Anyway, we add this to our code as well, because having a sound is just badass.
PHP Code:
public sh_hero_key(id, heroID, key)
{
if ( gHeroID != heroID ) return
if ( key == SH_KEYDOWN && is_user_alive(id) )
{
if ( gPlayerUltimateUsed[id] || gInvisTimer[id] > 0 )
{
sh_sound_deny(id)
}
gInvisTimer[id] = get_pcvar_num(pcvarTimer)
if ( get_pcvar_float(pcvarCooldown) > 0.0 )
{
ultimateTimer(id, get_pcvar_float(pcvarCooldown))
}
set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderTransAlpha, get_pcvar_num(pcvarAlpha))
gInvisMode[id] = true
new message[128]
format(message, 127, "You have now turned invisible")
set_hudmessage(50, 50, 255, -1.0, 0.28, 0, 0.0, 1.0, 0.0, 0.0, 54)
show_hudmessage(id, message)
emit_sound(id, CHAN_STATIC, gInvisSound, 0.1, ATTN_NORM, 0, PITCH_NORM)
}
}
Great, we are now done with the keydown forward. Next up is the stopSound forward. We have not yet used this forward anywhere, but surely it is used somewhere in the plugin, so we just create it now. The forward is this:
PHP Code:
public stopSound(id)
{
emit_sound(id, CHAN_STATIC, gInvisWomanSound, 0.1, ATTN_NORM, SND_STOP, PITCH_NORM)
}
So, the parameters in this forward must be stopping the sound, and the other emit_sound might be repeating the sound constantly while invisibility is on, and this is what stops it. We see SND_STOP as a constant, which is probably what stops it, but I really have no idea. Well, one thing I know is that gInvisWomanSound is not what I called the variable, but gInvisSound, so the forward would be:
PHP Code:
public stopSound(id)
{
emit_sound(id, CHAN_STATIC, gInvisSound, 0.1, ATTN_NORM, SND_STOP, PITCH_NORM)
}
Okay, so that was the stop of the sound.
Next up is the loop which we talked about in the beginning when we were looking at plugin_init.
PHP Code:
public inviswoman_loop()
{
for ( new id = 1; id <= SH_MAXSLOTS; id++ ) {
if ( gHasInvisWomanPower[id] && is_user_alive(id) ) {
if ( gInvisWomanTimer[id] > 0 ) {
new message[128]
format(message, 127, "%d second%s left of invisibility", gInvisWomanTimer[id], gInvisWomanTimer[id] == 1 ? "" : "s")
set_hudmessage(50, 50, 255, -1.0, 0.28, 0, 0.0, 1.0, 0.0, 0.0, 54)
show_hudmessage(id, message)
set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderTransAlpha, gAlpha)
gInvisWomanTimer[id]--
}
else if ( gInvisWomanTimer[id] == 0 ) {
gInvisWomanTimer[id]--
inviswoman_endmode(id)
}
}
}
}
So, what do we know about this?
We know that this runs each second infinitely, and we know that there is no player index which can be used.
We see a for. This is like if. This is called a for loop. How does this for look thing work?
Can you guess what I am about to write?
Oh yes, you did. We are going to look that up!
So, as this is a part of the scripting language itself and is used in many other scripting languages, such as PHP.
But we want to know how this works for pawn, and more importantly how it works in this context.
So, you should be familiar with the amxx wiki site:
http://wiki.amxmodx.org/index.php/Main_Page
In the intro to amxx scripting (
here) there is something about a for loop. Before actually reading this tutorial you should have read that page at first, but as many people just skip such things, I will try to explain it really quick.
A for loop is a loop which starts from 1 to a specified number. In this case the specified number is SH_MAXSLOTS. As you should know this can be changed in the superheromodconst.inc file. In this you can specify how many max players is available to join your server. Standard it is set to 32 as that is maximum of a cs 1.6 server. So in this case it will run this loop 32 times. Running through all the player slots, even if the player slot is not occupied.
So lets break it down:
PHP Code:
for ( new id = 1; id < SH_MAXSLOTS; id++ )
First a new variable is create. This is called the initialization of the loop. We start at 1 since index 0 is the server itself, and that can't possible have this hero since that is not a player.
Next is how many times to run this loop. In this case it is how much SH_MAXSLOTS is defined to (for me it is 32). Next means to add 1 more to id. So to start with id is player slot 1, then when that whole piece of code has been run, is makes id to 2, so it will be player slot 2 and so on until it hits 32. At 32 we have set it to stop. Remember this runs 32 times each second. This is a bit heavy for the server, but making it efficiently and you wont notice having them. But of course having 200 heroes with a loop each (or even two) is very heavy for the CPU in the server.
Now that you know a bit more about a for loop (even though you should have known this to start with) we move on.
Again looking at the loop, we see that in this loop it checks if the player spot has the hero and if he is alive. If these are correct, then check to see if the timer is more than 0, which means that the user has the power running. If the power is running then let him know how long time he has left. This is done using format and a HUD message. Next it sets the rendering once again. This is because if there is another hero setting like a glow, the invisibility is removed, then this sets the invisibility again. This is actually why you might see people blinking when they have many heroes, this is because the heroes are fighter over which one to control the render of the player. At last we minus 1 from gInvisWomanTimer. -- means -1 and ++ also means +1.
So, what if the timer is not bigger than 0? Then he must have used all his time. So, we have a check to see if timer is 0, and if it is minus 1 from it to make it -1. Next up a forward is created. So if the guy has used all his time, then go to the forward called inviswoman_endmode().
So, we finally know what the loop is doing and is actually pretty clever as it tells the player how much time he has left.
This we add to our plugin, and of course writing it so it fits with the variable names I have used:
First we actually make the loop as we didn't do that yet because we didn't know what it did before now:
PHP Code:
public plugin_init()
{
register_plugin("SUPERHERO Invis", "1.0", "Jelle")
new pcvarLevel = register_cvar("invis_level", "0")
pcvarTimer = register_cvar("invis_time", "5")
pcvarCooldown = register_cvar("invis_cooldown", "10")
pcvarAlpha = register_cvar("invis_alpha", "100")
gHeroID = sh_create_hero("Invis", pcvarLevel)
sh_set_hero_info(gHeroID, "Go invis", "Makes you invisible")
sh_set_hero_bind(gHeroID)
set_task(1.0, "inviswoman_loop", 0, "", 0, "b")
}
Next the loop forward:
PHP Code:
public inviswoman_loop()
{
for ( new id = 1; id <= SH_MAXSLOTS; id++ )
{
if ( gHasInvis[id] && is_user_alive(id) )
{
if ( gInvisTimer[id] > 0 )
{
new message[128]
format(message, 127, "%d second%s left of invisibility", gInvisTimer[id], gInvisTimer[id] == 1 ? "" : "s")
set_hudmessage(50, 50, 255, -1.0, 0.28, 0, 0.0, 1.0, 0.0, 0.0, 54)
show_hudmessage(id, message)
set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderTransAlpha, get_pcvar_num(pcvarAlpha))
gInvisTimer[id]--
}
else if ( gInvisTimer[id] == 0 )
{
gInvisTimer[id]--
invis_endmode(id)
}
}
}
}
Great, now for what to do in the invis_endmode forward:
PHP Code:
public inviswoman_endmode(id)
{
if ( !is_user_connected(id) ) return
gInvisWomanTimer[id] = -1
stopSound(id)
if ( gInvisWomanMode[id]) {
set_user_rendering(id)
gInvisWomanMode[id] = false
}
}
So, first a check to see if the user is connected. Why this? Well, because the player might have disconnected during this change from the loop to this forward. If this happens and this check is not there, then you will end up with a server crash since it can't do anything with a player spot which is not occupied. Next we make sure that gInvisWomanTimer is -1. Then we stop the sound using the stopSound forward which was made earlier on.
Then last a check to see if invisible mode is on, and if it is, then turn it off by making the variable gInvisWomanMode to false.
There is nothing really new here, so we are just going to add this to our plugin:
PHP Code:
public invis_endmode(id)
{
if ( !is_user_connected(id) ) return
gInvisTimer[id] = -1
stopSound(id)
if ( gInvisWomanMode[id] )
{
set_user_rendering(id)
gInvisWomanMode[id] = false
}
}
Lastly we have this:
PHP Code:
public inviswoman_death()
{
new id = read_data(2)
gPlayerUltimateUsed[id] = false
gInvisWomanTimer[id] = -1
if (gHasInvisWomanPower[id]) {
inviswoman_endmode(id)
}
}
As we found out earlier, this forward runs each time a player dies. In this old coded hero the forward needs to be registered, in these new ways of doing it, this event is already registered. Now what is it called? Yes, lets look it up!
Searching for death in the superheromod.inc file gives this result:
Code:
/**
* Called whenever a client dies.
* Death from sh_extra_damage will send correct info into this forward.
*
* @param victim The index of the victim.
* @param attacker The index of the attacker.
* @param headshot Equals 1 if death is by a headshot else 0.
* @param wpnDescription Name of the weapon that killed the victim.
* @noreturn
*/
forward sh_client_death(victim, attacker, headshot, const wpnDescription[]);
So, what we learn is that this forward returns the index of the victim and the attacker. It also returns if the victim died from a headshot or not and which weapon was used. Actually a lot of information is given. In the old days we had to get all of these informations our self, so this is just luxury that Vittu has done it like this.
So, now we know how to use this forward. What should happen when a player dies then?
At first the ultimate timer is reset (so the player can use the power right away when spawned again). Then gInvisWomanTimer is set to -1. Then a check to see if the user has the hero. If he has, then go to inviswoman_endmode which we did earlier and made it take off the power. So, we use this code in our plugin too. And as we actually only need to know the index of the guy who died, so we can just do it like this:
PHP Code:
public sh_client_death(victim)
{
gPlayerUltimateUsed[victim] = false
gInvisTimer[victim] = -1
if ( gHasInvis[victim] )
{
invis_endmode(victim)
}
}
And now that is it! You are done! Lets take a look at the final code:
PHP Code:
#include <superheromod>
new gHeroID
new gHasInvis[SH_MAXSLOTS+1]
new gInvisTimer[SH_MAXSLOTS+1]
new gInvisSound[] = "player/heartbeat1.wav"
new bool:gInvisMode[SH_MAXSLOTS+1]
new pcvarTimer
new pcvarCooldown
new pcvarAlpha
public plugin_init()
{
register_plugin("SUPERHERO Invis", "1.0", "Jelle")
new pcvarLevel = register_cvar("invis_level", "0")
pcvarTimer = register_cvar("invis_time", "5")
pcvarCooldown = register_cvar("invis_cooldown", "10")
pcvarAlpha = register_cvar("invis_alpha", "100")
gHeroID = sh_create_hero("Invis", pcvarLevel)
sh_set_hero_info(gHeroID, "Go invis", "Makes you invisible")
sh_set_hero_bind(gHeroID)
set_task(1.0, "inviswoman_loop", 0, "", 0, "b")
}
public sh_hero_init(id, heroID, mode)
{
if ( gHeroID != heroID ) return
switch(mode)
{
case SH_HERO_ADD:
{
gHasInvis[id] = true
}
case SH_HERO_DROP:
{
gHasInvis[id] = false
}
}
}
public sh_hero_key(id, heroID, key)
{
if ( gHeroID != heroID ) return
if ( key == SH_KEYDOWN && is_user_alive(id) )
{
if ( gPlayerUltimateUsed[id] || gInvisTimer[id] > 0 )
{
sh_sound_deny(id)
}
gInvisTimer[id] = get_pcvar_num(pcvarTimer)
if ( get_pcvar_float(pcvarCooldown) > 0.0 )
{
ultimateTimer(id, get_pcvar_float(pcvarCooldown))
}
set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderTransAlpha, get_pcvar_num(pcvarAlpha))
gInvisMode[id] = true
new message[128]
format(message, 127, "You have now turned invisible")
set_hudmessage(50, 50, 255, -1.0, 0.28, 0, 0.0, 1.0, 0.0, 0.0, 54)
show_hudmessage(id, message)
emit_sound(id, CHAN_STATIC, gInvisSound, 0.1, ATTN_NORM, 0, PITCH_NORM)
}
}
public stopSound(id)
{
emit_sound(id, CHAN_STATIC, gInvisSound, 0.1, ATTN_NORM, SND_STOP, PITCH_NORM)
}
public inviswoman_loop()
{
for ( new id = 1; id <= SH_MAXSLOTS; id++ )
{
if ( gHasInvis[id] && is_user_alive(id) )
{
if ( gInvisTimer[id] > 0 )
{
new message[128]
format(message, 127, "%d second%s left of invisibility", gInvisTimer[id], gInvisTimer[id] == 1 ? "" : "s")
set_hudmessage(50, 50, 255, -1.0, 0.28, 0, 0.0, 1.0, 0.0, 0.0, 54)
show_hudmessage(id, message)
set_user_rendering(id, kRenderFxGlowShell, 0, 0, 0, kRenderTransAlpha, get_pcvar_num(pcvarAlpha))
gInvisTimer[id]--
}
else if ( gInvisTimer[id] == 0 )
{
gInvisTimer[id]--
invis_endmode(id)
}
}
}
}
public invis_endmode(id)
{
if ( !is_user_connected(id) ) return
gInvisTimer[id] = -1
stopSound(id)
if ( gInvisMode[id] )
{
set_user_rendering(id)
gInvisMode[id] = false
}
}
public sh_client_death(victim)
{
gPlayerUltimateUsed[victim] = false
gInvisTimer[victim] = -1
if ( gHasInvis[victim] )
{
invis_endmode(victim)
}
}
Congratulations, you now know what everything in this hero does and how it works. You should also have gained enough knowledge on how to read other heroes and ripping them, or just reading and understanding them. This is actually all that you need to be making your own heroes, as you now know how to search for a native and how to actually use it.
Now remember, this is just my way of doing it. My way doesn't necessarily have to be the best way. I also do it like this because I think that is the easiest way to read my code. If you make your indentation in anyway way you like, but know this: If your indentation really sucks and I am having just the slightest difficulty reading your code, I am not going to bother helping you, and I bet many users in here feel the same way. If you want help, then write your code so we can read it and don't just cluster it all together. Spaces and white places does not add to the compiled plugin file size and the compiler will skip those, so there is no reason at all to not indent your code properly.
__________________