Closed xAstroBoy closed 4 months ago
Oh dear, there's a lot more problems than I thought.
public EnemyIdentity IdentifyEnemy(EnemyAI enemy) {
return enemy is null
? EnemyIdentity.None
: enemy switch {
CentipedeAI => EnemyIdentity.Centipede,
BaboonBirdAI => EnemyIdentity.Baboon,
FlowermanAI => EnemyIdentity.Flowerman,
ForestGiantAI => EnemyIdentity.ForestGiant,
HoarderBugAI => EnemyIdentity.HoarderBug,
JesterAI => EnemyIdentity.Jester,
MaskedPlayerEnemy => EnemyIdentity.Masked,
MouthDogAI => EnemyIdentity.MouthDog,
NutcrackerEnemyAI => EnemyIdentity.Nutcracker,
PufferAI => EnemyIdentity.Puffer,
SandWormAI => EnemyIdentity.Sandworm,
SpringManAI => EnemyIdentity.Springman,
_ => EnemyIdentity.Default,
};
}
Why did you not just return the enemy instead? You are making a lot of unnecessary indirections, which you later have to indirect back again.
Please be patient while I fix this.
Oh dear, there's a lot more problems than I thought.
public EnemyIdentity IdentifyEnemy(EnemyAI enemy) { return enemy is null ? EnemyIdentity.None : enemy switch { CentipedeAI => EnemyIdentity.Centipede, BaboonBirdAI => EnemyIdentity.Baboon, FlowermanAI => EnemyIdentity.Flowerman, ForestGiantAI => EnemyIdentity.ForestGiant, HoarderBugAI => EnemyIdentity.HoarderBug, JesterAI => EnemyIdentity.Jester, MaskedPlayerEnemy => EnemyIdentity.Masked, MouthDogAI => EnemyIdentity.MouthDog, NutcrackerEnemyAI => EnemyIdentity.Nutcracker, PufferAI => EnemyIdentity.Puffer, SandWormAI => EnemyIdentity.Sandworm, SpringManAI => EnemyIdentity.Springman, _ => EnemyIdentity.Default, }; }
Why did you not just return the enemy instead? You are making a lot of unnecessary indirections, which you later have to indirect back again.
Please be patient while I fix this.
that is how to identify which enemy class is to specifically control without casting the enemy over and over?
You could probably just do this.
T IdentifyEnemy(EnemyAI enemy) where T : EnemyAI {
...
}
without casting the enemy over and over?
Also, you are doing a lot of casting anyways.
case EnemyIdentity.Centipede:
return ((CentipedeAI)this.EnemyToPossess).GetSecondarySkillName();
case EnemyIdentity.Baboon:
return ((BaboonBirdAI)this.EnemyToPossess).GetSecondarySkillName();
case EnemyIdentity.HoarderBug:
return ((HoarderBugAI)this.EnemyToPossess).GetSecondarySkillName();
case EnemyIdentity.Jester:
return ((JesterAI)this.EnemyToPossess).GetSecondarySkillName();
case EnemyIdentity.Nutcracker:
return ((NutcrackerEnemyAI)this.EnemyToPossess).GetSecondarySkillName();
case EnemyIdentity.Puffer:
return ((PufferAI)this.EnemyToPossess).GetSecondarySkillName();
case EnemyIdentity.Sandworm:
return ((SandWormAI)this.EnemyToPossess).GetSecondarySkillName();
case EnemyIdentity.MouthDog:
return ((MouthDogAI)this.EnemyToPossess).GetSecondarySkillName();
I am still looking really superficially. Give me a while to dig into it.
It would've probably been better to use a IController
interface since every extension has a common method. We'll see.
You could probably just do this.
T IdentifyEnemy(EnemyAI enemy) where T : EnemyAI { ... }
without casting the enemy over and over?
Also, you are doing a lot of casting anyways.
case EnemyIdentity.Centipede: return ((CentipedeAI)this.EnemyToPossess).GetSecondarySkillName(); case EnemyIdentity.Baboon: return ((BaboonBirdAI)this.EnemyToPossess).GetSecondarySkillName(); case EnemyIdentity.HoarderBug: return ((HoarderBugAI)this.EnemyToPossess).GetSecondarySkillName(); case EnemyIdentity.Jester: return ((JesterAI)this.EnemyToPossess).GetSecondarySkillName(); case EnemyIdentity.Nutcracker: return ((NutcrackerEnemyAI)this.EnemyToPossess).GetSecondarySkillName(); case EnemyIdentity.Puffer: return ((PufferAI)this.EnemyToPossess).GetSecondarySkillName(); case EnemyIdentity.Sandworm: return ((SandWormAI)this.EnemyToPossess).GetSecondarySkillName(); case EnemyIdentity.MouthDog: return ((MouthDogAI)this.EnemyToPossess).GetSecondarySkillName();
yes, but the switch case casts only based off which enemy is, and the enum acts as a identity
Have you seen IEnemyPrompter
?
Have you seen
IEnemyPrompter
?
nvm
@winstxnhdw another issue is seconday attack while you are dead and controlling a enemy you risk of starting a vote for the ship to leave early
@winstxnhdw another issue is seconday attack while you are dead and controlling a enemy you risk of starting a vote for the ship to leave early
Good catch. We can patch that out.
@winstxnhdw i want to use Update() and add a better primary and secondary since with your input system sometimes it fails and it does not hold on the attacks. Also a way to set the enemy walk/run speed would be handy as well, since controlcompany does that to make it as natural as possible.
i want to use Update() and add a better primary and secondary since with your input system sometimes it fails and it does not hold on the attacks.
Can you tell me how it fails? You might be implementing it wrongly. Hold commands must be set within the update loop like this.
void Update() {
InputListener.onShiftButtonHold?.Invoke(Keyboard.current[Key.LeftShift].isPressed);
InputListener.onFButtonHold?.Invoke(Keyboard.current[Key.F].isPressed);
InputListener.onRButtonHold?.Invoke(Keyboard.current[Key.R].isPressed);
InputListener.onEButtonHold?.Invoke(Keyboard.current[Key.E].isPressed);
foreach ((Func<bool> keyPressed, Action eventAction) in this.InputActions) {
if (!keyPressed()) continue;
eventAction();
}
}
i want to use Update() and add a better primary and secondary since with your input system sometimes it fails and it does not hold on the attacks.
Can you tell me how it fails? You might be implementing it wrongly. Hold commands must be set within the update loop like this.
void Update() { InputListener.onShiftButtonHold?.Invoke(Keyboard.current[Key.LeftShift].isPressed); InputListener.onFButtonHold?.Invoke(Keyboard.current[Key.F].isPressed); InputListener.onRButtonHold?.Invoke(Keyboard.current[Key.R].isPressed); InputListener.onEButtonHold?.Invoke(Keyboard.current[Key.E].isPressed); foreach ((Func<bool> keyPressed, Action eventAction) in this.InputActions) { if (!keyPressed()) continue; eventAction(); } }
yeah, the secondary needs to be a hold attack, because you need to keep pressing the button to make the jester crank and when it pops out the secondary has to be released, ill investigate better, but im not sure about that, as well we need to disable ping scan until we stop possessing the enemy
Also a way to set the enemy walk/run speed would be handy as well, since controlcompany does that to make it as natural as possible.
Would subscribing to the onLeftBracketPress
and onRightBracketPress
events to change speed work?
Also a way to set the enemy walk/run speed would be handy as well, since controlcompany does that to make it as natural as possible.
Would subscribing to the
onLeftBracketPress
andonRightBracketPress
events to change speed work?
No need, we need just to change the jester speed to make it faster when it pops out, not all enemies needs that. same for coilhead when pressing shift it needs to play it's accelerated animation
yeah, the secondary needs to be a hold attack, because you need to keep pressing the button to make the jester crank and when it pops out the secondary has to be released, ill investigate better, but im not sure about that, as well we need to disable ping scan until we stop possessing the enemy
Yup so what you need to do is something like this.
public static event Action? onLeftButtonHold;
void Update() {
InputListener.onShiftButtonHold?.Invoke(Keyboard.current[Key.LeftShift].isPressed);
InputListener.onFButtonHold?.Invoke(Keyboard.current[Key.F].isPressed);
InputListener.onRButtonHold?.Invoke(Keyboard.current[Key.R].isPressed);
InputListener.onEButtonHold?.Invoke(Keyboard.current[Key.E].isPressed);
InputListener.onLeftButtonHold?.Invoke(Mouse.current.leftButton.isPressed);
foreach ((Func<bool> keyPressed, Action eventAction) in this.InputActions) {
if (!keyPressed()) continue;
eventAction();
}
}
No need, we need just to change the jester speed to make it faster when it pops out, not all enemies needs that. same for coilhead when pressing shift it needs to play it's accelerated animation
Can't we do this programmatically? Like if jester is not in box -> set enemy speed to higher?
yeah, the secondary needs to be a hold attack, because you need to keep pressing the button to make the jester crank and when it pops out the secondary has to be released, ill investigate better, but im not sure about that, as well we need to disable ping scan until we stop possessing the enemy
Yup so what you need to do is something like this.
public static event Action? onLeftButtonHold; void Update() { InputListener.onShiftButtonHold?.Invoke(Keyboard.current[Key.LeftShift].isPressed); InputListener.onFButtonHold?.Invoke(Keyboard.current[Key.F].isPressed); InputListener.onRButtonHold?.Invoke(Keyboard.current[Key.R].isPressed); InputListener.onEButtonHold?.Invoke(Keyboard.current[Key.E].isPressed); InputListener.onLeftButtonHold?.Invoke(Mouse.current.leftButton.isPressed); foreach ((Func<bool> keyPressed, Action eventAction) in this.InputActions) { if (!keyPressed()) continue; eventAction(); } }
Go ahead and apply it, im working to figure how to disable the ping scan input until we stop the enemy posession.
No need, we need just to change the jester speed to make it faster when it pops out, not all enemies needs that. same for coilhead when pressing shift it needs to play it's accelerated animation
Can't we do this programmatically? Like if jester is not in box -> set enemy speed to higher?
Exactly , is just that i cant figure how to do it with the possession mod. EDIT : a way to block rotation would be handy as well since some enemies are not supposed to rotate when are frozen lol
No need, we need just to change the jester speed to make it faster when it pops out, not all enemies needs that. same for coilhead when pressing shift it needs to play it's accelerated animation
Can't we do this programmatically? Like if jester is not in box -> set enemy speed to higher?
Exactly , is just that i cant figure how to do it with the possession mod.
Something like this?
public static void ReleaseSecondarySkill(this JesterAI instance) {
if (!instance.IsInState(JesterState.Cranking)) return;
instance.SetState(JesterState.PopOut);
PossessionMod.Instance.RigidbodyKeyboard.baseSpeed = 999.9f;
}
EDIT : a way to block rotation would be handy as well since some enemies are not supposed to rotate when are frozen lol
Since we are using a rigidbody controller, IIRC there's a boolean we can flip to disable rotations.
No need, we need just to change the jester speed to make it faster when it pops out, not all enemies needs that. same for coilhead when pressing shift it needs to play it's accelerated animation
Can't we do this programmatically? Like if jester is not in box -> set enemy speed to higher?
Exactly , is just that i cant figure how to do it with the possession mod.
Something like this?
public static void ReleaseSecondarySkill(this JesterAI instance) { if (!instance.IsInState(JesterState.Cranking)) return; instance.SetState(JesterState.PopOut); PossessionMod.Instance.RigidbodyKeyboard.baseSpeed = 999.9f; }
EDIT : a way to block rotation would be handy as well since some enemies are not supposed to rotate when are frozen lol
Since we are using a rigidbody controller, IIRC there's a boolean we can flip to disable rotations.
you can check how controlcompany by reading the dll with dnspy does, they set the PlayerControl speed by multiplying it by 16, and yeah 999.9f is over exagerated.
Possibly add a Patch that disables the UI when in possession.
Possibly add a Patch that disables the UI when in possession.
already did by disabling the early vote hud.
@winstxnhdw so far it can be merged, i fixed the issue with grabbing scrap and now we can control both Hoarding Bug and the monkey to grab the items and drop them without any issues.
I think @D1GQ wants all the HUDs to be disabled during possession?
I think @D1GQ wants all the HUDs to be disabled during possession?
that can be added later, but the main functionality is completed.
@winstxnhdw everything is ready to be merged, only spring's control needs to be actually implemented to make it walk and not slide.
Huh? What happened to all my changes?
Okay, nvm. Some are still there. I'll finish the rest tomorrow.
There's a bug where if an enemy despawns or you get kicked while possessing it, then you're unable to to possess any other enemies until you restart.
There's also issue where the door gets absolutely spammed trying to open and close it as an enemy. And it seems disabling The death HUD doesn't work when possessing.
@winstxnhdw a health checker to see if a possessed enemy is dead to eject PossessionMod and a way to give AI the enemy control and override it would be nice. Haven't figured how to fix the door issue .
AI the enemy control and override it would be nice
What?
Haven't figured how to fix the door issue .
Just use TriggerMod
interact??
Haven't figured how to fix the door issue .
Just use
TriggerMod
interact??
yeah triggermod can do it, but when you are dead is not working to open/close doors.
Nope, it still works.
Nope, it still works.
not dedicated to the enemy itself tho? for example if you possess a enemy and you want to make it leave the facility that wouldn't work.
Oh, you mean the entrances? Honestly, there is nothing wrong with noclipping outside. Let's figure it out next time.
I just spent 7 hours on this. This is the last time I will be accepting a PR of such dubious quality. The next time I see a PR that will take more more than 2 hours to fix, I am just closing it. I can't waste so much time anymore.
Closes #250