GetRandomAvaliablePlayer¶
This method obtains a suitable player party member index using the regular targetting rules.
private int GetRandomAvaliablePlayer(bool nullable)
Parameters¶
nullable
: If true, this will use an alternative targetting scheme that may return -1 meaning to not target anyone. There is an overload without this that behaves the same as if false was sent. NOTE: The true version has broken logic, see the section below for details.
Procedure¶
The logic depends on nullable's value
nullable is true¶
If forceattack
isn't -1, it is returned.
Otherwise, there will be attempts to find a random player party member to target. Each attempt involves generating a random one using uniformly random probabilities between each of them. For the target to be accepted, its hp
must be above 0. The amount of times this is attempted is the amount of player party members. If a target is accepted it is returned, otherwise, -1 is returned and the caller has to handle this logic since no one will be targetted.
Problems with nullable true logic¶
There are some issues with this logic compared to the nullable false version which are bad enough to be considered broken:
- This scheme fails to account for the front player party member meaning it does not matter who is in the front
- This scheme fails to account for the
LeafCloak
medal even when it is equipped meaning it does not matter if it is equipped on someone or not - This scheme fails to account for the
Hook
medal even when it is equipped meaning it does not matter if it is equipped on someone or not - This scheme may not return a valid target which may force the caller to abort the attack or to try again, but there is never a guarantee that an accepted target is returned
- This scheme fails to account for the eatenby (Only would have mattered for a
Pitcher
enemy, but they do not use this targetting scheme under normal gameplay)
However, some enemies intentionally uses it in their action codes. The following enemies involves it at least once as part of their DoAction logic:
WildChomper
(via SpitSeed)ChomperBrute
(via SpitSeed)VenusBoss
(called directly and via ShakeSeed)TANGYBUG
(via ShakeSeed)SeedlingKing
(via ShakeSeed)BeeTurret
BeeBoss
FalseMonarch
MidgeBroodmother
UltimaxTank
MotherChomper
Despite the game using it under normal gameplay, it is highly recommended to never pass true to the nullable parameter. It fails to account for too much and it can lead to undesired logic where the caller might not be able to find a suitable target.
nullable is false¶
If forceattack
isn't -1 and the player party member coresponding to it doens't have an eatenby
, it is returned.
Otherwise, there is an infinite loop that starts:
- A random
partypointer
element (aplayerdata
index) is generated by generating a number from -2 (inclusive) to the amount of player party members (exclusive) clamped from 0 to the amount of player party members (this essentially biases to target the first party member more) - If the player party member's
hp
is 0 or itseatenby
exists, the target is rejected and the loop restarts - Otherwise, if the player party member has the
LeafCloak
medal equipped, the target is rejected, but this can only happen once: if another target passes thehp
andeatenby
checks, it is automatically accepted and returned - Otherwise, if the player party member doesn't have the
Hook
medal equipped, but another player party member in the player party has it equipped, the target is rejected, but this can only happen once: if another target passes thehp
andeatenby
checks, it is automatically accepted and returned - Otherwise, the target is accepted and returned
The overall targetting odds are as follows (assuming neither or either of the Hook
or LeafCloak
medal is equipped on someone, but not both, see the details below on how this is handled):
Amount of player party members | Who has Hook ? |
Who has LeafCloak ? |
Odds front | Odds second | Odds third |
---|---|---|---|---|---|
2 | No one | No one | 3/4 | 1/4 | N/A |
2 | No one | Front | 9/16 | 7/16 | N/A |
2 | No one | Second | 15/16 | 1/16 | N/A |
2 | Front | No one | 15/16 | 1/16 | N/A |
2 | Second | No one | 9/16 | 7/16 | N/A |
3 | No one | No one | 3/5 | 1/5 | 1/5 |
3 | No one | Front | 9/25 | 8/25 | 8/25 |
3 | No one | Second | 18/25 | 1/25 | 6/25 |
3 | No one | Third | 18/25 | 6/25 | 1/25 |
3 | Front | No one | 21/25 | 2/25 | 2/25 |
3 | Second | No one | 12/25 | 9/25 | 4/25 |
3 | Third | No one | 12/25 | 4/25 | 9/25 |
If both medals are equipped on the same player party members, the LeafCloak
take priority causing the Hook
medal to be ignored.
If both medals are eqiuipped on 2 different player party members, both will technically take effect, but in a way that the LeafCloak
effects doesn't change the odds in practice because it causes a reroll while as the Hook
would already have caused it. Since the LeafCloak
medal doesn't contribute to any changes in odds in this case, it is equivalent to say that in such a case, the Hook
medal gets ignored here.
GetSingleTarget¶
There is a parameterless method that ends up calling GetRandomAvailablePlayer with nullable to false. That method is called GetSingleTarget.
The only thing it does is take the return of GetRandomAvailablePlayer and set it to playertargetID
which is better for use in DoAction for an enemy party member because it allows to easily set who the enemy will be targetting.
It also sets playertargetentitty
to the corresponding battleentity of the playertargetID
, but only if it's not negative (which can't happen normally).