Detecting multiple powerups...
Moderator: InsideQC Admins
8 posts
• Page 1 of 1
Detecting multiple powerups...
Ok, so say I wanted to make some code that detects if a player has acquired more than one powerup... what is a way to do this??
ive tried
and
and neither work correctly... I'm sure this is a trivial fix, but I'm not sure what the correct way to detect the player's acquired items is..?
any help appreciated!
ive tried
- Code: Select all
if ((self.items == IT_INVISIBILITY) &&
(self.items == IT_QUAD) &&
(self.items == IT_INVULNERABILITY))
{
sprint (other, "Oh noes! Powerful player running around...\n");
// more code here
}
and
- Code: Select all
if ((self.classname == "item_artifact_invisibility") &&
(self.classname == "item_artifact_super_damage") &&
(self.items == "item_artifact_invulnerability"))
{
sprint (other, "Oh noes! Powerful player running around...\n");
// more code here
}
and neither work correctly... I'm sure this is a trivial fix, but I'm not sure what the correct way to detect the player's acquired items is..?
any help appreciated!
-

dayfive - Posts: 77
- Joined: Fri Nov 10, 2006 9:48 pm
The problem is that 'other' in this context refers to the player, while 'self' refers to the powerup. Because this is the touch function of the powerup, that powerup will be self when the touch function is triggered. Likewise, the player may also have a touch function and, when that's triggered, the player will be self.
Basically, you'll want something like this (not tested!):
This checks to see if the entity that's touching the item has the three powerups then, if it has, does a bprint (broadcasts message to all players) to let everyone know.
You might also notice that I've replaced the == in the if statement with &. This is because powerups, like most items, are stored in the player entity as bit flags. They work a bit like this:
So, basically, you can use a single .items variable to store all information on lots of items, since each one only uses a single binary digit. It's probably not worth worrying about it too much yet, but if still need help with this, just ask and we'll explain what we can.
If you wanted to hide the message from the player that's just picked up the item, you'd need to use sprint again, but you'd need to call it once for each other player in the game, not just use 'other'![/code]
Basically, you'll want something like this (not tested!):
- Code: Select all
if ((other.items & IT_INVISIBILITY) &&
(other.items & IT_QUAD) &&
(other.items & IT_INVULNERABILITY))
{
bprint ("Oh noes! Powerful player running around...\n");
// more code here
}
This checks to see if the entity that's touching the item has the three powerups then, if it has, does a bprint (broadcasts message to all players) to let everyone know.
You might also notice that I've replaced the == in the if statement with &. This is because powerups, like most items, are stored in the player entity as bit flags. They work a bit like this:
- Code: Select all
IT_Shotgun = 1 = 0001
IT_Super_Shotgun = 2 = 0010
IT_Nailgun = 4 = 0100
IT_Super_Nailgun = 8 = 1000
Bitwise OR: 0001 | 0100 = 0101
Bitwise AND: 1010 & 0011 = 0010
So, basically, you can use a single .items variable to store all information on lots of items, since each one only uses a single binary digit. It's probably not worth worrying about it too much yet, but if still need help with this, just ask and we'll explain what we can.
If you wanted to hide the message from the player that's just picked up the item, you'd need to use sprint again, but you'd need to call it once for each other player in the game, not just use 'other'![/code]
-

Quake Matt - Posts: 129
- Joined: Sun Jun 05, 2005 9:59 pm
Hi Quake Matt!
Thanks for your reply.
so I tried your example and it didn't work out of the box, but what you said makes a lot of sense. A thought occurred that, if you touch the powerup and it checks for all 3, it won't return true unless it's the second powerup of a certain type you get, since you wont actually have all 3 at the instant you touch the third.
This is what ended up working for me based on your suggestions and advice
i'm sure there's a more elegant way to accomplish this, but that's just the first thing i thought of.... if anyone else has a better way, please share!
For the full test example, I was using this (in void() powerup_touch right before "if (deathmatch)")
so it basically just resets the timers so all three powerups end at exactly the same time. i tested it in dm3.bsp
thanks again for your help!
Thanks for your reply.
Quake Matt wrote:The problem is that 'other' in this context refers to the player, while 'self' refers to the powerup. Because this is the touch function of the powerup, that powerup will be self when the touch function is triggered. Likewise, the player may also have a touch function and, when that's triggered, the player will be self.
...
This checks to see if the entity that's touching the item has the three powerups then, if it has, does a bprint (broadcasts message to all players) to let everyone know.
so I tried your example and it didn't work out of the box, but what you said makes a lot of sense. A thought occurred that, if you touch the powerup and it checks for all 3, it won't return true unless it's the second powerup of a certain type you get, since you wont actually have all 3 at the instant you touch the third.
This is what ended up working for me based on your suggestions and advice
- Code: Select all
if (((other.items & IT_INVISIBILITY) && (other.items & IT_QUAD)) ||
((other.items & IT_INVISIBILITY) && (other.items & IT_INVULNERABILITY)) ||
((other.items & IT_QUAD) && (other.items & IT_INVULNERABILITY)))
{
bprint (other.netname);
bprint (" has acquired all 3 powerups!\n");
}
i'm sure there's a more elegant way to accomplish this, but that's just the first thing i thought of.... if anyone else has a better way, please share!
For the full test example, I was using this (in void() powerup_touch right before "if (deathmatch)")
- Code: Select all
if (((other.items & IT_INVISIBILITY) && (other.items & IT_QUAD)) ||
((other.items & IT_INVISIBILITY) && (other.items & IT_INVULNERABILITY)) ||
((other.items & IT_QUAD) && (other.items & IT_INVULNERABILITY)))
{
bprint (other.netname);
bprint (" has acquired all 3 powerups!\n");
other.invisible_time = 1;
other.invisible_finished = time + 30;
other.invincible_time = 1;
other.invincible_finished = time + 30;
other.super_time = 1;
other.super_damage_finished = time + 30;
}
so it basically just resets the timers so all three powerups end at exactly the same time. i tested it in dm3.bsp
thanks again for your help!
-

dayfive - Posts: 77
- Joined: Fri Nov 10, 2006 9:48 pm
Currently the way you have it, the message will go off if the player has two of the three powerups and then touches any powerup. So if they got quad, then pent, then a second quad, the message would go off even though they only have those two powerups. What you could do is put the original check for all three powerups in, but put it further down in powerup_touch, specifically after the line
other.items = other.items | self.items;
At this point the player does have all three items, so you can do the check and it'll succeed.
other.items = other.items | self.items;
At this point the player does have all three items, so you can do the check and it'll succeed.
- Preach
- Posts: 122
- Joined: Thu Nov 25, 2004 7:20 pm
Preach wrote:Currently the way you have it, the message will go off if the player has two of the three powerups and then touches any powerup. So if they got quad, then pent, then a second quad, the message would go off even though they only have those two powerups. What you could do is put the original check for all three powerups in, but put it further down in powerup_touch, specifically after the line
other.items = other.items | self.items;
At this point the player does have all three items, so you can do the check and it'll succeed.
oh! i see... thanks for pointing this out! i tried your suggestion and it works as expected. i think i understand the concept much better than the first post in this thread.
thank you Preach and Quake Matt!
-

dayfive - Posts: 77
- Joined: Fri Nov 10, 2006 9:48 pm
in powerup_touch....
after other.items = other.items | self.item;
add...

after other.items = other.items | self.item;
add...
- Code: Select all
if (other.items & IT_INVISIBILITY | IT_INVULNERABILITY | IT_QUAD)
{
other.invisible_time = other.invincible_time = other.super_time = 1;
other.invisible_finished = other.invincible_finished = other.super_damage_finished = time + 30;
}
- r00k
- Posts: 1110
- Joined: Sat Nov 13, 2004 10:39 pm
That'll detect if you have any one or more of them...
if ((other.items & IT_INVISIBILITY | IT_INVULNERABILITY | IT_QUAD) == IT_INVISIBILITY | IT_INVULNERABILITY | IT_QUAD)
would be the full solution, equivalent to Preach's solution
Might need more parentheses in there though, not sure.
if ((other.items & IT_INVISIBILITY | IT_INVULNERABILITY | IT_QUAD) == IT_INVISIBILITY | IT_INVULNERABILITY | IT_QUAD)
would be the full solution, equivalent to Preach's solution
Might need more parentheses in there though, not sure.
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
- Sajt
- Posts: 1215
- Joined: Sat Oct 16, 2004 3:39 am
8 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 1 guest