Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Medical rewrite bug fixes #6523

Merged
merged 6 commits into from Aug 14, 2018
Merged

Conversation

redbery
Copy link
Contributor

@redbery redbery commented Aug 12, 2018

When merged this pull request will:

  • Fix medical menu reopen setting
  • Fix second delay on execution condition which had a broken macro causing players to fall through cardiac arrest to death immediately
  • Fix people reporting 40 HR (set from leaving cardiac arrest state) when dead
  • Fix players having old stats on respawn (including references to arrays causing wounds to the old corpse to apply to the new player too)
  • Fix locality issue on unit init causing JiP to reset all variables (wounds etc) on all units
  • Fix updateHeartRate being allowed to go passed the target heart rate. This is an especially large issue as it made it completely impossible to perform CPR. During CPR the vitals would not be checked leading to the maximum deltaT of 10. On the first tick of handle vitals once CPR was successfully completed the function would be entered with a HR of 40 and the target HR would be 80. This would make the function
    40 + ((80 - 40) / 2 )*10 = 240, which would be a HR high enough to push the unit back into cardiac arrest.

Note: I realize the respawn issue has been noted as fixed in #6518, but I can't find the respawn XEH noted in that PR. If I missed or misunderstood this I will of course happily take out my proposed fix. Also my apologies for the seemingly random mix of fixes. These were all the problems we ran into when running a test operation with the rewrite branch today.

@@ -19,6 +19,7 @@ class Extended_PostInit_EventHandlers {
class Extended_Init_EventHandlers {
class CAManBase {
class ADDON {
onRespawn = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only accepts number 1, no strings. Booleans don't exist in config.
https://github.com/CBATeam/CBA_A3/blob/master/addons/xeh/fnc_compileEventHandlers.sqf#L155

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about that. Took it from the XEH wiki and didn't notice the define statement 4 lines above it... Should be fixed now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just looked in the config viewer as I was wondering why this mistake didn't cause unwanted behavior and noticed that it already got converted from true to 1. I'll leave the change in for clarity.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not all binarizers do this. Mikero converts it despite no define, which causes a lot of other problems.

if (_bloodVolume < BLOOD_VOLUME_CLASS_2_HEMORRHAGE) then {
_targetHR = _heartRate * (_targetBP / (45 max _meanBP));
};
if (_painLevel > 0.2) then {
_targetHR = _targetHR max (80 + 50 * _painLevel);
};
_targetHR = _targetHR + _hrTargetAdjustment;
_targetHR = (_targetHR + _hrTargetAdjustment) max 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't _targetHR always greater than 0? There is no need for max 0 in my opinion

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hrTargetAdjustment can be a rather large negative value depending on current medication I believe. I don't know if it could ever go below 0 because of that but I'd think its worth ensuring it won't. Will remove it if that's really wanted but it seems like taking a bit of a gamble just to save 6 characters.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good, we're just moving the max 0 up from line 73 where it was previously 👍


_hrChange = round(_targetHR - _heartRate) / 2;
} else {
_hrChange = -round(_heartRate / 10);
};
_heartRate = (_heartRate + _deltaT * _hrChange) max 0;
if (_hrChange < 0) then {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can put the whole new If statement directly under the _hrChange calculation and spare it since it is redundant:

   _hrChange = round(_targetHR - _heartRate) / 2;
   _heartRate = (_heartRate + _deltaT * _hrChange) min _targetHR;
} else ...
   

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry, I don't think I understand what you are suggesting. The heart rate is currently doing a min or max with _targetHR depending on if we are increasing or decreasing our heart rate. Wouldn't the change you are suggesting here cause any gradual change lowering the HR to happen immediately instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After going through the code more closely these lines look good to me 👍

This doesn't fix the issue of incorrectly large deltaT first tick after cardiac arrest, but you're right that we don't want the heart rate to pass the target anyway so it should stay because it does fix that issue (theoretically deltaT could reach 10 at any time).

For the exiting cardiac arrest deltaT issue, I think we should still be running handleUnitVitals while in cardiac arrest because it appears to handle other things not related to heart rate too, if we don't then we should refresh the stored lastTimeUpdated value on the unit when exiting cardiac arrest to avoid similar issues to the one revealed here.

@@ -46,6 +46,7 @@ private _heartRate = GET_HEART_RATE(_unit);

if !IN_CRDC_ARRST(_unit) then {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this preventing the unit from entering when in cardiac arrest?

On the first tick of handle vitals once CPR was successfully completed the function would be entered with a HR of 40 and the target HR would be 80. This would make the function
40 + ((80 - 40) / 2 )*10 = 240, which would be a HR high enough to push the unit back into cardiac arrest.

Regarding the XEH for the respawn issue:
https://github.com/acemod/ACE3/pull/6518/files#diff-081751a9b9de93a0af75655dce42c674R22

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is only resetting the statemachine though and not resetting the variables such as openWounds right? My worry is that if the new unit does not override the variables from the old unit on respawn it will have a reference to the actual arrays meaning they will receive any updates to the old arrays (and therefor receive wounds when shooting the old corpse).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check indeed prevents the unit when entering when in cardiac arrest, but that doesn't matter too much as the updateUnitVitals and therefore updateHeartRate is not being called when in cardiac arrest. Problem is that the first time when the unit leaves cardiac arrest state, updateUnitVitals will run updateHeartRate with a _deltaT of 10 as updateUnitVitals hasn't been run in a while. Even if that would be fixed by running updateUnitVitals when in cardiac arrest, I don't believe that it is intentional to ever report a new HR after adjustment beyond the targetHR.

@TheMagnetar TheMagnetar added this to the Medical Rewrite milestone Aug 12, 2018
@@ -19,6 +19,7 @@ class Extended_PostInit_EventHandlers {
class Extended_Init_EventHandlers {
class CAManBase {
class ADDON {
onRespawn = 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I overlooked that this wasn't a respawn XEH in my comment on #6518

@kymckay
Copy link
Member

kymckay commented Aug 12, 2018

All looks good except I need to look more closely at the last point (there's definitely an unhandled scenario in the code there though) 👍

Copy link
Contributor

@thojkooi thojkooi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One suggestion to avoid mixing goals between components. Maybe the engine component may be a better fit, but I don't think it belongs in the statemachine logic.

@@ -19,4 +19,7 @@ params ["_unit"];
// Send a local event before death
[QEGVAR(medical,death), [_unit]] call CBA_fnc_localEvent;

_unit setVariable [VAR_HEART_RATE, 0, true];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be done in the medical vitals component through an eventhandler I think.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well spotted, I would agree that an EH is better here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would we also want to change leftStateCardiacArrest then?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably also want to do it for that function, yes. That may require introducing some new events though. Does not have to be done in this PR, imo. But we should create an issue for it if we do not. I will leave that to your discretion @redbery.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I'll have the time to do that today as it is somewhat involved which would mean it would need to wait until next weekend. Think it is better to create a new issue for it if you don't mind.

@thojkooi thojkooi added the kind/bug-fix Release Notes: **FIXED:** label Aug 12, 2018
@thojkooi thojkooi added this to Open in Medical Focus Feature via automation Aug 12, 2018
Copy link
Member

@kymckay kymckay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good fixes and has revealed an issue in the vitals loop when exiting cardiac arrest (time delta is incorrectly at max of 10 because loop doesn't run while in cardiac arrest). We can fix this in a different PR.

I agree with @thojkooi's requested changes, but I think we should merge this and change that in a new PR (since it's also relevant to a file not changed here).

if (_bloodVolume < BLOOD_VOLUME_CLASS_2_HEMORRHAGE) then {
_targetHR = _heartRate * (_targetBP / (45 max _meanBP));
};
if (_painLevel > 0.2) then {
_targetHR = _targetHR max (80 + 50 * _painLevel);
};
_targetHR = _targetHR + _hrTargetAdjustment;
_targetHR = (_targetHR + _hrTargetAdjustment) max 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good, we're just moving the max 0 up from line 73 where it was previously 👍


_hrChange = round(_targetHR - _heartRate) / 2;
} else {
_hrChange = -round(_heartRate / 10);
};
_heartRate = (_heartRate + _deltaT * _hrChange) max 0;
if (_hrChange < 0) then {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After going through the code more closely these lines look good to me 👍

This doesn't fix the issue of incorrectly large deltaT first tick after cardiac arrest, but you're right that we don't want the heart rate to pass the target anyway so it should stay because it does fix that issue (theoretically deltaT could reach 10 at any time).

For the exiting cardiac arrest deltaT issue, I think we should still be running handleUnitVitals while in cardiac arrest because it appears to handle other things not related to heart rate too, if we don't then we should refresh the stored lastTimeUpdated value on the unit when exiting cardiac arrest to avoid similar issues to the one revealed here.

@thojkooi
Copy link
Contributor

@SilentSpike yes, sounds good.

@kymckay
Copy link
Member

kymckay commented Aug 14, 2018

I've opened two issues so we don't forget the issues touched upon here:
#6530
#6531

@kymckay kymckay merged commit 5fbaf42 into acemod:medical-rewrite Aug 14, 2018
Medical Focus Feature automation moved this from Open to Completed Aug 14, 2018
@redbery redbery deleted the medical-rewrite branch August 14, 2018 21:44
BaerMitUmlaut pushed a commit that referenced this pull request Aug 5, 2019
* Fix medical menu not reopening regardless of setting
* Ensure no heartrate or bloodpressure on death
* Fix status variables not being reset on respawn
* Fix JIP resetting status variables for all units
* Fix heart rate adjustment overflow and
@PabstMirror PabstMirror modified the milestones: Medical Rewrite, 3.13.0, 3.13.0-temp3 Dec 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug-fix Release Notes: **FIXED:**
Projects
Development

Successfully merging this pull request may close these issues.

None yet

6 participants