-
Notifications
You must be signed in to change notification settings - Fork 44
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
Add BotRemoteAngles and BotAngles #113
Conversation
… adds remote bot button, BotStop assigns current weapon
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the code quality of this PR has peaked superb levels. Good Job.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some unsafe access of ptr needs to be fixed, otherwise looks okay 👍
@@ -311,6 +317,43 @@ namespace Components | |||
g_botai[entref.entnum].meleeDist = static_cast<int8_t>(dist); | |||
g_botai[entref.entnum].active = true; | |||
}); | |||
|
|||
GSC::Script::AddMethod("BotRemoteAngles", [](const Game::scr_entref_t entref) // Usage: <bot> BotRemoteAngles(<int>, <int>); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not immediatly obvious to me what a function called "BotRemoteAngles" does nor what its parameters are, without reading the implementation. It would be nice to document them (the function "sets" the yaw and pitch, even though none of these three word appear in the function name!)
Is there a reason why the "remote angles" is not set at the same time as the "angles" in the other function?
The code does not inform me on why they need to be done separately and the name in the engine ("remote angle") i'm not sure what it means in this context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look at usercmd_t, angles are for the viewangles (aiming), and remote angles are for the pred missile.
|
||
GSC::Script::AddMethod("BotAngles", [](const Game::scr_entref_t entref) // Usage: <bot> BotAngles(<float>, <float>, <float>); | ||
{ | ||
const auto* ent = GSC::Script::Scr_GetPlayerEntity(entref); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function can return nullptr !
Please always check for nullptr before accessing the ent's members, lest a bad GSC script could instantly crash the game.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess, but since GSC VM wouldn't lie about the entref, it wouldn't be needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It also returns nullptr if it's not a player!
In general if a function can return a nullptr then it's better to make a check for the pointer being non-NULL as a general rule, otherwise unexpected inputs can create bugs that are very hard to understand for players (usually just a flavour of Fatal Error)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm good catch, I hadn't actually looked at that function; I had thought that since all the other builtins had the same pattern, it was just safe to keep it consistent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's true, it can never be a null pointer because of the long jumps.
Because it was never marked as no return in the definitions at functions.hpp the compiler will complain so those return nullptrs are just there for that reason.
A refactor initiative would be to use c++ exceptions like here https://git.alterware.dev/alterware/iw6-mod/src/branch/master/src/client/component/gsc/script_extension.cpp#L300
powered by this hook which uses try/catch https://git.alterware.dev/alterware/iw6-mod/src/branch/master/src/client/component/gsc/script_extension.cpp#L56
By using c++ exceptions to handle this in code it would no longer require to leave those nullptrs as the throw statement is already a no return
alternatively leave stuff as it is without any c++ stuff and either comment the behaviour of the function or mark objecterror and all other similar functions as no return
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see! :)
Indeed if the function is to never return it should be marked as noreturn and therefore those return nullptr
should not be there. Additional short comments (just saying "this long jumps out, no return needed" or something like that) would be much appreciated
The GSC VM is a part of the engine I almost never worked with so I'm just doing due dilligence of checking your implem, sorry if my remarks are a bit naive.
I looked a bit in the engine and the Scr_Error does call Sys_Error which is a noreturn, however there are several conditions to calling Sys_Error (0x2040D06 OR !0x201A40F) and they're not documented on my end, I'm not sure what they are.
Do you confirm that Scr_Error will always call Sys_Error and therefore never return?
If so I will trust your word and go through with your change, no problem, but if you're not sure please double check 🙇♀️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A longjmp or exit (sys_error) will always occur, if a Scr_Error had actually continued execution, the VM would be in an inconsistent state, causing undefined behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.evaluate will ALWAYS be false in ship builds, .evaluate is used for when there is a script debugger attached to the game, and it is trying to execute GSC opcodes pushed by the debugger.
GSC::Script::AddMethod("BotRemoteAngles", [](const Game::scr_entref_t entref) // Usage: <bot> BotRemoteAngles(<int>, <int>); | ||
{ | ||
const auto* ent = GSC::Script::Scr_GetPlayerEntity(entref); | ||
if (!Game::SV_IsTestClient(ent->s.number)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had also just copy pasted the other method builtins for consistency
@@ -54,10 +56,11 @@ namespace Components | |||
{ "sprint", Game::CMD_BUTTON_SPRINT }, | |||
{ "leanleft", Game::CMD_BUTTON_LEAN_LEFT }, | |||
{ "leanright", Game::CMD_BUTTON_LEAN_RIGHT }, | |||
{ "ads", Game::CMD_BUTTON_ADS }, | |||
{ "ads", Game::CMD_BUTTON_ADS | Game::CMD_BUTTON_THROW }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be okay to map CMD_BUTTON_THROW to a new action named "throw" and then simply set both actions in GSC, therefore managing akimbo in GSC, rather than merging the commands in the client?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ads
isn't an actual command in the engine; the correct name for ads
would be speed
, so having ads
a compound of throw and speed would be okay? and have speed
only the ads button bit, and throw
its own
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm gonna check up every PR this saturday and draft a new release 💆♀️
What does this PR do?
Add
BotRemoteAngles
andBotAngles
builtin methods for botsFixes
ads
BotAction
not throwing (allows bots to shoot akimbo weapons)Adds
remote
BotAction
BotStop
assigns current weaponThanks for the contribution! Please provide a concise description of the problem this request solves.
How does this PR change IW4x's behaviour?
Are there any breaking changes? Will any existing behaviour change?
Specify the new expected behaviour if this PR adds a new gameplay feature or alters an existing game mechanic. You may provide an image or video showing the changes.
Anything else we should know?
Add any other context about your changes here.
Did you check all the boxes?
closes #XXXX
in comment to auto-close issue when PR is merged)