Trouble with Pick-ups

Hey, thanks for clicking on this thread.

I’m trying to create an item that drops on a player’s death, despawns when the player respawns, and can be picked up if a player on a certain hero gets close enough to it. The items are set to player variables, so every player has a unique instance of one. The spawn and despawn commands are working perfectly, but the pick-up is another problem entirely; I know what it is, but I don’t know the solution to it. Players are able to pick up their own drops at the moment, instead of only being exclusively obtainable to one single hero.

I think the best way to describe what I’m making is “it’s like Reaper’s soul globes from before they were removed”. I want a specific player to be able to pick up the dropped item (from any friendly players), and have a certain effect applied exclusively to them.

Is there a way for a single hero to access the player variables of all characters, without referring to lobby slots? I’m sure there is, but I just can’t figure it out. I’d love some help, thank you.

I feel like you might want to use Is True For Any(All Players) to detect if someone is close enough to the pickup(condition for the rule), and then First Of(Sorted Array(All Players, [distance between the current array element and the pickup])) to find the player who picked it up.

But yeah, the various values that can check every value of an array like Is True For All/Any and Filtered/Sorted Array are useful for this kind of thing.

I’ll definitely try and look into that. I’m still learning how to use the workshop, and I’ve only recently been exploring the filtered array. It’s good to know I’m on the right track, I’m just doing the wrong thing.

So would the condition you described look roughly like Is true for any (all players (team of (event player)), first of (sorted array (value in array (player variable (event player, a) 1), current array element))) == true? With the event player being the player who dropped the item, and A1 being the item’s value in the index?

I was thinking something like this for the condition, it will return true if someone is close enough to pick up the pick-up:

conditions
{
Is True For Any(All Living Players(Team Of(Event Player)), Compare(Distance Between(Eye Position(Current Array Element), [INSERT POSITION OF PICK-UP HERE]), <=, [INSERT RADIUS OF PICK-UP HERE]))
}

This should be used in an action, it will return the player who picked up the pick-up:

First Of(Sorted Array(All Living Players(Team Of(Event Player)), Distance Between(Eye Position(Current Array Element), [INSERT POSITION OF PICK-UP HERE])))

I decided to use All Living Players instead of All Players just to make sure that nothing weird happens with dead players picking up pick-ups, and used Eye Position just because it’s usually in the middle of most heroes (you can use Position Of instead if it causes issues, since Position Of is consistently at the bottom of every hero.).

Realising it might be useful if I include the (broken) code I’m using:

Event: Ongoing - Each player
Team: All
Player: All

Value in array (player variable (event player, A), 0) == true (To check whether the item still exists or not)
Distance between (Players on hero (Hero (Moira), team of (Event player)), Value in array (Player variable (event player, A), 1)) <= 2 (Moira is the only player I want to be able to pick up the item, and I only want her to be able to pick up items dropped by her team, A1 is the item)


Heal (Event player, event player, 20)
Set ultimate charge (Event player, Add (Ultimate charge percent (Event player), 3))

Obviously there are more actions to destroy the pickup, but I didn’t think it was too important to include those. They’re just Destroy effect (Value in array (Player variable (event player, A), 1)) sort of things.

I know that with the way it’s been written, the code is applying the heal and the ultimate charge to the event player, who in this case is the dead person instead of the Moira trying to pick it up. But I’m not sure what the correct code is…

Thanks for your patience. I appreciate it. I’m testing your code at the moment!

This compare the distance between the event player and the created effect of the dead player instead of the distance between the created effect of event player and ally of event player

rule("Rule 1")
{
event
{
	Ongoing - Each Player;
	All;
	All;
}

conditions
{
	Hero Of(Event Player) == Hero(Moira);
	Distance Between(Event Player, Value In Array(Player Variable(Filtered Array(All Players(Team Of(Event Player)), Compare(
		Value In Array(Player Variable(Current Array Element, A), 0), ==, True)), A), 1)) <= 2;
}

actions
{
	Heal(Event Player, Event Player, 20);
	Set Ultimate Charge(Event Player, Add(Ultimate Charge Percent(Event Player), 3));
	Destroy Effect(Value In Array(Player Variable(Filtered Array(All Players(Team Of(Event Player)), And(Compare(Distance Between(
		Position Of(Event Player), Position Of(Current Array Element)), <=, 2), Compare(Value In Array(Player Variable(
		Current Array Element, A), 0), ==, True))), A), 1));
}
}

I’ve tried the code, and the healing and ultimate charge goes to Moira. However, the ones picking up their own drops are still the test bots instead of Moira. I can also be healed anywhere on the map if one of the bots picks up their drops (which they do on respawn, for some reason?) Should I include the code I used to create and destroy the effects to see if I’ve done something wrong there?

Change the “distance between” rule by this one :

conditions
{
Distance Between(Event Player, Value In Array(Player Variable(Filtered Array(All Players(Team Of(Event Player)), And(Compare(
	Value In Array(Player Variable(Current Array Element, A), 0), ==, True), Compare(Current Array Element, !=, Event Player))),
	A), 1)) <= 2;
}

Should resolve both problems

Ah, it didn’t, unfortunately… <:)
The bots are still picking up their own drops when they respawn, and crediting it to me.

I’ve double checked I wrote the code you sent me correctly, so I’m genuinely not sure what the problem is…

can you send the full code so i can chek it ?

And by the way you can copy/past all of the code (no need to retype it)

Edit : i forgot to add it but you can put the following condition :

conditions
{
Value In Array(Player Variable(Event Player, A), 0) == False;
}

I can send it, but I play on console, so I DO have to retype, unfortunately. <:)
I’ll revert back to the original code I used for the pick-up command, in case it’s important at all:

To initialise, I used "set player variable at index (event player, A, 0, false)".

RULE: SPAWN ON DEATH
Event: Player died
Team: All
Player: All

CONDITION:
- Is dead (Event player) == True

ACTION:
- Set player variable at index (event player, A, 0, true)
- Create effect (Players on hero (Hero (Moira), team of (event player)), orb, orange, add (position of (event player), vector (0, 1, 0)) 0.1, visible to)
- Set player variable at index (event player, a, 1, Last created entity)
- Create effect (Players on hero (Hero (Moira), team of (event player)), bad aura, orange, add (position of (event player), vector (0, 1, 0)) 1, visible to)
- Set player variable at index (event player, a, 2, Last created entity)
- Create effect (Players on hero (Hero (Moira), team of (event player)), light shaft, yellow, add (position of (event player), vector (0, 1, 0)) 0.05, visible to)
- Set player variable at index (event player, a, 3, Last created entity)
- Create effect (Players on hero (Hero (Moira), team of (event player)), bad aura sound, orange, add (position of (event player), vector (0, 1, 0)) 100, visible to)
- Set player variable at index (event player, a, 4, Last created entity)

RULE: DESTROY ON PLAYER RESPAWN
Event: Ongoing - Each player
Team: All
Player: All

CONDITION:
- Value in array (player variable (event player, a), 0) == true
- Is alive (event player) == true

ACTIONS:
- Destroy effect (value in array (player variable (event player, a), 1))
- Destroy effect (value in array (player variable (event player, a), 2))
- Destroy effect (value in array (player variable (event player, a), 3))
- Destroy effect (value in array (player variable (event player, a), 4))
- Set player variable at index (event player, a, 0, false)

RULE: PICK-UP
Event: Ongoing - Each player
Team: All
Player: All

CONDITION:
- Value in array (player variable (event player, A), 0) == true 
- Distance between (Players on hero (Hero (Moira), team of (Event player)), Value in array (Player variable (event player, A), 1)) <= 2

ACTION:
- Heal (Event player, event player, 20)
- Set ultimate charge (Event player, Add (Ultimate charge percent (Event player), 3))
    - Destroy effect (value in array (player variable (event player, a), 1))
    - Destroy effect (value in array (player variable (event player, a), 2))
    - Destroy effect (value in array (player variable (event player, a), 3))
    - Destroy effect (value in array (player variable (event player, a), 4))
    - Set player variable at index (event player, a, 0, false)

Sorry that took so long, but console workshop isn’t too friendly on a developer.

Ok i finnaly figured out why it didn’t work (and how to fix it, that’s what take so long) !
Create and Destroy rules are almost the same (you can delet the “is dead” condition on Create and you can use add “up”, “down”, “right”, “left”, “forward”, “backward” instead of adding vector (0,1,0)

But here is the code if you wanna look (share code so you don’t have to type everyting :wink: : S0QY5 )

Full Code
  rule("Create")
{
event
{
	Player Died;
	All;
	All;
}

actions
{
	Set Player Variable At Index(Event Player, A, 0, True);
	Create Effect(Players On Hero(Hero(Moira), Team Of(Event Player)), Orb, Orange, Add(Position Of(Event Player), Up), 0.100,
		Visible To);
	Set Player Variable At Index(Event Player, A, 1, Last Created Entity);
	Create Effect(Players On Hero(Hero(Moira), Team Of(Event Player)), Bad Aura, Orange, Add(Position Of(Event Player), Up), 1,
		Visible To);
	Set Player Variable At Index(Event Player, A, 2, Last Created Entity);
	Create Effect(Players On Hero(Hero(Moira), Team Of(Event Player)), Light Shaft, Yellow, Add(Position Of(Event Player), Up), 0.050,
		Visible To);
	Set Player Variable At Index(Event Player, A, 3, Last Created Entity);
	Create Effect(Players On Hero(Hero(Moira), Team Of(Event Player)), Bad Aura Sound, Orange, Add(Position Of(Event Player), Up), 100,
		Visible To);
	Set Player Variable At Index(Event Player, A, 4, Last Created Entity);
}
}

rule("Destroy")
{
event
{
	Ongoing - Each Player;
	All;
	All;
}

conditions
{
	Is Alive(Event Player) == True;
	Value In Array(Player Variable(Event Player, A), 0) == True;
}

actions
{
	Set Player Variable At Index(Event Player, A, 0, False);
	Destroy Effect(Value In Array(Player Variable(Event Player, A), 1));
	Destroy Effect(Value In Array(Player Variable(Event Player, A), 2));
	Destroy Effect(Value In Array(Player Variable(Event Player, A), 3));
	Destroy Effect(Value In Array(Player Variable(Event Player, A), 4));
}
}

rule("Take")
{
event
{
	Ongoing - Each Player;
	All;
	All;
}

conditions
{
	Filtered Array(All Players(Team Of(Event Player)), Compare(Value In Array(Player Variable(Current Array Element, A), 0), ==, True))
		!= Empty Array;
	Is Alive(Event Player) == True;
	Hero Of(Event Player) == Hero(Moira);
	Distance Between(Event Player, Add(Position Of(Filtered Array(All Players(Team Of(Event Player)), Compare(Value In Array(
		Player Variable(Current Array Element, A), 0), ==, True))), Up)) <= 2;
}

actions
{
	Heal(Event Player, Event Player, 20);
	Set Ultimate Charge(Event Player, Add(Ultimate Charge Percent(Event Player), 3));
	Destroy Effect(Value In Array(Player Variable(Filtered Array(All Players(Team Of(Event Player)), And(Compare(Distance Between(
		Position Of(Event Player), Add(Position Of(Current Array Element), Up)), <=, 2), Compare(Value In Array(Player Variable(
		Current Array Element, A), 0), ==, True))), A), 1));
	Destroy Effect(Value In Array(Player Variable(Filtered Array(All Players(Team Of(Event Player)), And(Compare(Distance Between(
		Position Of(Event Player), Add(Position Of(Current Array Element), Up)), <=, 2), Compare(Value In Array(Player Variable(
		Current Array Element, A), 0), ==, True))), A), 2));
	Destroy Effect(Value In Array(Player Variable(Filtered Array(All Players(Team Of(Event Player)), And(Compare(Distance Between(
		Position Of(Event Player), Add(Position Of(Current Array Element), Up)), <=, 2), Compare(Value In Array(Player Variable(
		Current Array Element, A), 0), ==, True))), A), 3));
	Destroy Effect(Value In Array(Player Variable(Filtered Array(All Players(Team Of(Event Player)), And(Compare(Distance Between(
		Position Of(Event Player), Add(Position Of(Current Array Element), Up)), <=, 2), Compare(Value In Array(Player Variable(
		Current Array Element, A), 0), ==, True))), A), 4));
	Set Player Variable At Index(Filtered Array(All Players(Team Of(Event Player)), And(Compare(Distance Between(Position Of(
		Event Player), Add(Position Of(Current Array Element), Up)), <=, 2), Compare(Value In Array(Player Variable(
		Current Array Element, A), 0), ==, True))), A, 0, False);
}
}

The problem came from :

 Distance Between(Event Player, Add(Position Of(Filtered Array(All Players(Team Of(Event Player)), Compare(Value In Array(
		Player Variable(Current Array Element, A), 0), ==, True))), Up)) <= 2

which cause the distance to be always <= 2 if the filtered array was empty (0 dead player) so i have to add this condition on the take rule :

Filtered Array(All Players(Team Of(Event Player)), Compare(Value In Array(Player Variable(Current Array Element, A), 0), ==, True))
		!= Empty Array

Edit Share code and code because i forgot to reset the A,0 variable to false when picking up the orb

There’s a slight problem; for some reason, I’m finding that some of the pickups won’t be picked up until the first one to spawn has been taken, but only sometimes…? They become obtainable after the first drop to spawn has been destroyed or taken, though. Do you think a wait command somewhere might be able to fix that? Other than that, the code is working absolutely perfectly, and I can’t thank you enough. I’ve been trying to figure this out for about a week now!

I really appreciate your help and your patience!