| 118 | */ |
| 119 | |
| 120 | int AEquipment::getAccuracy(BodyState bodyState, MovementState movementState, |
| 121 | WeaponAimingMode fireMode, bool thrown) |
| 122 | { |
| 123 | float accuracy = 0.0f; |
| 124 | auto agent = ownerAgent ? ownerAgent : (ownerUnit ? ownerUnit->agent : nullptr); |
| 125 | if (agent) |
| 126 | { |
| 127 | accuracy = agent->modified_stats.accuracy; |
| 128 | } |
| 129 | |
| 130 | if (thrown) |
| 131 | { |
| 132 | return (int)accuracy; |
| 133 | // Throwing accuracy is unaffected by movement, stance or mode of fire |
| 134 | } |
| 135 | |
| 136 | StateRef<AEquipmentType> payload = getPayloadType(); |
| 137 | if (!payload) |
| 138 | { |
| 139 | payload = *type->ammo_types.begin(); |
| 140 | } |
| 141 | |
| 142 | if (this->type->type != AEquipmentType::Type::Weapon) |
| 143 | { |
| 144 | LogError("getAccuracy (non-thrown) called on non-weapon"); |
| 145 | return 0; |
| 146 | } |
| 147 | |
| 148 | // Accuracy calculation algorithm |
| 149 | |
| 150 | // Take agent and weapon's accuracy |
| 151 | |
| 152 | auto agentAccuracy = accuracy; |
| 153 | auto payloadAccuracy = |
| 154 | type->type == AEquipmentType::Type::Weapon ? (float)payload->accuracy : 100.0f; |
| 155 | |
| 156 | // Calculate dispersion, the inverse of accuracy, and scale values to 0-1 for simplicity |
| 157 | |
| 158 | float agentDispersion = 1.0f - agentAccuracy / 100.0f; |
| 159 | float weaponDispersion = 1.0f - payloadAccuracy / 100.0f; |
| 160 | |
| 161 | // Weapon dispersion is half as important |
| 162 | weaponDispersion *= 0.5f; |
| 163 | |
| 164 | // Firing mode: Auto increases dispersion and Aimed decreases by factors of 2 |
| 165 | agentDispersion *= 0.5f * (float)fireMode; |
| 166 | |
| 167 | // Moving affects dispersion |
| 168 | switch (movementState) |
| 169 | { |
| 170 | case MovementState::None: |
| 171 | agentDispersion *= 0.8f; |
| 172 | break; |
| 173 | case MovementState::Running: |
| 174 | agentDispersion *= 1.25f; |
| 175 | break; |
| 176 | default: |
| 177 | agentDispersion *= 0.95f; |
nothing calls this directly
no test coverage detected