Yes.
Dreamy Cecil
Creator of
Recent community posts
With discussions, you can basically have multiple comment sections. And I think that’s actually better when you need to discuss a specific thing instead of littering the same place and then searching for the appropriate comment that continues into a hidden chain to add even more to it.
Just create a separate topic if you intend on discussing a very specific thing in detail, otherwise post single comments in these pinned topics, which are on topic.
You can code virtually any gameplay mechanic you want but I don’t think I’m capable of explaining it in simple terms/steps to someone who doesn’t really code.
Even disregarding the programming language, it all depends on how a specific mechanic works and the abstract steps you come up with in order to implement it.
In your case, the abstract steps would be something like this:
(1) Figure out the start angle for shooting the laser to the side of the current target.
(2) Rotate this angle in some direction with each game tick until it reaches a certain limit.
(3) Each time the angle changes, the laser needs to be physically shot using a raycast in the calculated direction of the current angle.
(4) Render the laser beam from the source to the hit point of a raycast as long as the attack is active.
I don’t know what that is or how it behaves but if you want a hitscan laser that follows the player instead of directly targeting them, I can propose this:
(1) Define a target angle for your enemy’s hitscan as ANGLE3D (e.g. m_aTowardsTarget) and optionally set it to the enemy’s orientation angle on start.
(2) When the enemy begins attacking, calculate an angle towards the target (m_penEnemy in enemy’s case) with a small delay before the actual attack:
FLOAT3D vToTarget = (m_penEnemy->GetPlacement().pl_PositionVector - GetPlacement().pl_PositionVector).Normalize();
ANGLE3D aToTarget;
DirectionVectorToAngles(vToTarget, aToTarget);
m_aTowardsTarget = aToTarget;
(3) During a continuous hitscan in a loop, calculate an angle difference between the current target angle and the angle towards the target. Reuse the same code as in step 2 but instead of setting angle to m_aTowardsTarget, do this:
aToTarget -= m_aTowardsTarget;
aToTarget(1) = NormalizeAngle(aToTarget(1));
aToTarget(2) = NormalizeAngle(aToTarget(2));
m_aTowardsTarget += aToTarget / 2;
Here the difference is divided by 2 to make it follow the target twice as slow. Adjust as needed or even clamp the maximum speed of each angle like this:
aToTarget(1) = Clamp(NormalizeAngle(aToTarget(1)), -30.0f, +30.0f);
(4) Then use the resulting angle in the CCastRay as the source:
CPlacement3D plLaser(vLaserPosRelativeToEnemy, m_aTowardsTarget);
CCastRay crLaser(this, plLaser, 500);
Or if the laser needs to just go from one side to another in the general direction of the player, add an initial angle to that target angle so it starts to the side and just add a specific fixed amount to the angle each loop iteration instead of the difference relative to the target.
If you wanna modify your existing function, pass a unique index or something into each FirePlasmaRayAlt() call and then adjust the angle based on the index.
Replace CalcWeaponPositionImprecise() with CalcWeaponPosition() and modify plPlasmaRay.pl_OrientationAngle after its call. Or use plPlasmaRay.Rotate_Airplane() to add rotation relative to the current view.
Update 22 lacks new particle functions for the Beam entity and a ModelsF/Enemies/Mental/Mental.h file for the Mental entity.
I appreciate the separation of files. I hope whenever there’s a new update, it lists which files specifically have been updated. Or even better - append an update version to each file link like “(Update 22)” to know exactly when the last change happened.
Also, coop players spawn inside walls in The Final Encounter level.
If you only intend on toggling particle effects without any logic surrounding them, you can remove Active() and Inactive() procedures entirely and replace this block:
// go into active or inactive state
if (m_bActive) {
jump Active();
} else {
jump Inactive();
}
With this:
// Wait for the game to start
autowait(0.05f);
wait() {
on (EActivate) : {
m_bActive = TRUE;
resume;
}
on (EDeactivate) : {
m_bActive = FALSE;
resume;
}
otherwise() : { resume; }
}
Hey, if you want some help with packing mod files to reduce the unpacked size and to get rid of unnecessary files, you can use my Dreamy GRO application. I just released an update for it that supports mods and all kinds of files (even DLL). I have a short wiki page for it as well, if you have questions about it, or you can just ask me.
But I must warn you that it’s not perfect and might miss some files in specific circumstances, so I recommend testing new updates on clean game installations before releasing them.
Usually (as in never, but if I ever had to) I’d just create a pull request on GitHub, but since the code isn’t in any repository, I guess I could send them here.
If I end up sending entire files, you’ll have to make sure not to overwrite your own changes that aren’t in the latest sources yet. I always prefix comments before my changes with [Cecil] in the beginning, so maybe you could look those up.
Regarding the IDs, it would only cause problems if there were any collisions. Properties are usually identified by both ID and type, so because those properties had different types, it was fine.
As for the component, the issues it currently has are (1) inability to precache it and (2) it would always play the previous sound because it’s always found first. If it was something else (e.g. a model), it would’ve caused crashes when it expects one type but ends up finding another under the same ID.
Where could I submit potential fixes to the code if I happen to find bugs?
Meanwhile, I found a few duplicate IDs in classes that I recommend to renumber:
- m_fSize or m_penFireFX property in Mamut.es (change ID of one of them from 3 to 1)
- m_penGhostBusterRay or m_iHydroBarrel property in PlayerWeapons.es (change ID of the first one from 310 to 246 or the second one from 310 to 311)
- SOUND_DEATH_RUN component in Cerberus.es (change ID from 55 to 57)
Hello, I like what you’re doing here, just awesome. However, I have a major problem with the way it’s packaged, more specifically the source files.
What is the point of packing the entire development folder with literally thousands of Alpha, TFE and TSE resources? I have tried building the mod myself and all I needed is to copy EntitiesMP and GameMP folders on top of the clean SDK (and some folders with model headers).
If you can, please start packing the source code very minimally.
(1) Firstly, please remove everything other than .h files from AREP, Models, ModelsF and ModelsMP under Sources. It can be done manually by searching under each folder in explorer using “NOT type:h NOT kind:=folder” query (no quotes) and then pressing Ctrl+A to select all files and deleting them.
(2) Secondly, you may also want to delete Debug and Release build folders from EntitiesMP and GameMP because the files in there are generated each time you build the source code anyway.
(3) Thirdly, you probably only want to pack EntitiesMP, GameGUIMP, GameMP, AREP, Models, ModelsF and ModelsMP folders from Sources. But, if you’re really worried about forgetting something or just too lazy to do it, just pack the Sources folder alone.
From my testing, you can simply place the release files on top of the sources and the mod that you build yourself works as intended.
And finally, if you still wish to share all the development resources for some reason, just pack them separately and please get rid of the vanilla assets that are already in SE1_00.gro.
P.S. The current source files lack the HiveBrain entity. In fact, there are absolutely no changes to the code since Update 16 from what I can see.
Yes, you can play Bright Island through The Second Encounter.
If your The Second Encounter installation is in Steam, it should detect every other game and mount them automatically.
If it’s outside of Steam (or under a different Steam library folder), navigate to Options -> Classics Patch -> Config properties and setup paths to Revolution and its workshop. Or change them directly in the configuration file (SSRDir and SSRWorkshop properties).
If you setup Revolution path but leave workshop path empty, it will automatically detect it relative to Revolution path.
Dude! My first idea for a game was almost exactly like this! It had a different goal but ultimately you had to code Neuro’s movement as well! Though I was mainly drawing inspiration from Human Resource Machine and I think yours is from Scratch and similar “learning programming” applications. Actually happy to see this game :)