Refactor script related funcs/modules
This commit is contained in:
parent
6d80943380
commit
77c2043006
@ -29,10 +29,10 @@ namespace Components
|
|||||||
/* Actions */
|
/* Actions */
|
||||||
int buttons;
|
int buttons;
|
||||||
/* Movement */
|
/* Movement */
|
||||||
int8 forward;
|
int8_t forward;
|
||||||
int8 right;
|
int8_t right;
|
||||||
/* Weapon */
|
/* Weapon */
|
||||||
unsigned short weapon;
|
uint16_t weapon;
|
||||||
} BotMovementInfo_t;
|
} BotMovementInfo_t;
|
||||||
|
|
||||||
static BotMovementInfo_t g_botai[MAX_G_BOTAI_ENTRIES];
|
static BotMovementInfo_t g_botai[MAX_G_BOTAI_ENTRIES];
|
||||||
@ -71,15 +71,6 @@ namespace Components
|
|||||||
{ "9", 33554432 },
|
{ "9", 33554432 },
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int Bots::GetClientNum(Game::client_s* cl)
|
|
||||||
{
|
|
||||||
unsigned int num;
|
|
||||||
|
|
||||||
num = ((byte*)cl - (byte*)Game::svs_clients) / sizeof(Game::client_s);
|
|
||||||
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Bots::IsValidClientNum(unsigned int cNum)
|
bool Bots::IsValidClientNum(unsigned int cNum)
|
||||||
{
|
{
|
||||||
return (cNum >= 0) && (cNum < (unsigned int)*Game::svs_numclients);
|
return (cNum >= 0) && (cNum < (unsigned int)*Game::svs_numclients);
|
||||||
@ -96,9 +87,9 @@ namespace Components
|
|||||||
|
|
||||||
if (bots.exists())
|
if (bots.exists())
|
||||||
{
|
{
|
||||||
std::vector<std::string> names = Utils::String::Explode(bots.getBuffer(), '\n');
|
auto names = Utils::String::Explode(bots.getBuffer(), '\n');
|
||||||
|
|
||||||
for (auto name : names)
|
for (auto& name : names)
|
||||||
{
|
{
|
||||||
Utils::String::Replace(name, "\r", "");
|
Utils::String::Replace(name, "\r", "");
|
||||||
name = Utils::String::Trim(name);
|
name = Utils::String::Trim(name);
|
||||||
@ -121,37 +112,32 @@ namespace Components
|
|||||||
botName = Utils::String::VA("bot%d", ++botId);
|
botName = Utils::String::VA("bot%d", ++botId);
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy_s(buffer, 0x400, Utils::String::VA(connectString, num, botName, protocol, checksum, statVer, statStuff, port), 0x400);
|
_snprintf_s(buffer, 0x400, _TRUNCATE, connectString, num, botName, protocol, checksum, statVer, statStuff, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bots::Spawn(unsigned int count)
|
void Bots::Spawn(int count)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
for (auto i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
Scheduler::OnDelay([]()
|
Scheduler::OnDelay([]()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 3; ++i)
|
auto* ent = Game::SV_AddTestClient();
|
||||||
{
|
if (ent == nullptr)
|
||||||
Game::gentity_t* entRef = Game::SV_AddTestClient();
|
return;
|
||||||
if (entRef)
|
|
||||||
{
|
Scheduler::OnDelay([ent]()
|
||||||
Scheduler::OnDelay([entRef]()
|
|
||||||
{
|
{
|
||||||
Game::Scr_AddString("autoassign");
|
Game::Scr_AddString("autoassign");
|
||||||
Game::Scr_AddString("team_marinesopfor");
|
Game::Scr_AddString("team_marinesopfor");
|
||||||
Game::Scr_Notify(entRef, Game::SL_GetString("menuresponse", 0), 2);
|
Game::Scr_Notify(ent, Game::SL_GetString("menuresponse", 0), 2);
|
||||||
|
|
||||||
Scheduler::OnDelay([entRef]()
|
Scheduler::OnDelay([ent]()
|
||||||
{
|
{
|
||||||
Game::Scr_AddString(Utils::String::VA("class%d", Utils::Cryptography::Rand::GenerateInt() % 5));
|
Game::Scr_AddString(Utils::String::VA("class%u", Utils::Cryptography::Rand::GenerateInt() % 5u));
|
||||||
Game::Scr_AddString("changeclass");
|
Game::Scr_AddString("changeclass");
|
||||||
Game::Scr_Notify(entRef, Game::SL_GetString("menuresponse", 0), 2);
|
Game::Scr_Notify(ent, Game::SL_GetString("menuresponse", 0), 2);
|
||||||
}, 1s);
|
}, 1s);
|
||||||
}, 1s);
|
}, 1s);
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 500ms * (i + 1));
|
}, 500ms * (i + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,7 +152,7 @@ namespace Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ping = Game::Scr_GetInt(0);
|
const auto ping = Game::Scr_GetInt(0);
|
||||||
|
|
||||||
if (ping < 0 || ping > 999)
|
if (ping < 0 || ping > 999)
|
||||||
{
|
{
|
||||||
@ -174,21 +160,8 @@ namespace Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::gentity_t* gentity = Script::getEntFromEntRef(id);
|
const auto* gentity = Script::GetEntFromEntRef(id);
|
||||||
Game::client_t* client = Script::getClientFromEnt(gentity);
|
auto* client = Script::GetClientFromEnt(gentity);
|
||||||
unsigned int clientNum = GetClientNum(client);
|
|
||||||
|
|
||||||
if (!Bots::IsValidClientNum(clientNum))
|
|
||||||
{
|
|
||||||
Game::Scr_Error("^1SetPing: Need to call on a player entity!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client->state < 3)
|
|
||||||
{
|
|
||||||
Game::Scr_Error("^1SetPing: Need to call on a connected player!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!client->isBot)
|
if (!client->isBot)
|
||||||
{
|
{
|
||||||
@ -196,198 +169,136 @@ namespace Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
client->ping = (short)ping;
|
client->ping = static_cast<int16_t>(ping);
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("isBot", [](Game::scr_entref_t id) // Usage: <bot> isBot();
|
Script::AddFunction("IsBot", [](Game::scr_entref_t id) // Usage: <bot> IsBot();
|
||||||
{
|
{
|
||||||
Game::gentity_t* gentity = Script::getEntFromEntRef(id);
|
const auto* gentity = Script::GetEntFromEntRef(id);
|
||||||
Game::client_t* client = Script::getClientFromEnt(gentity);
|
const auto* client = Script::GetClientFromEnt(gentity);
|
||||||
unsigned int clientNum = GetClientNum(client);
|
|
||||||
|
|
||||||
if (!Bots::IsValidClientNum(clientNum))
|
|
||||||
{
|
|
||||||
Game::Scr_Error("^1isBot: Need to call on a player entity!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client->state < 3)
|
|
||||||
{
|
|
||||||
Game::Scr_Error("^1isBot: Needs to be connected.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Game::Scr_AddInt(client->isBot);
|
Game::Scr_AddInt(client->isBot);
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("botStop", [](Game::scr_entref_t id) // Usage: <bot> botStop();
|
Script::AddFunction("BotStop", [](Game::scr_entref_t id) // Usage: <bot> BotStop();
|
||||||
{
|
{
|
||||||
Game::gentity_t* gentity = Script::getEntFromEntRef(id);
|
const auto* gentity = Script::GetEntFromEntRef(id);
|
||||||
Game::client_t* client = Script::getClientFromEnt(gentity);
|
const auto* client = Script::GetClientFromEnt(gentity);
|
||||||
unsigned int clientNum = GetClientNum(client);
|
|
||||||
|
|
||||||
if (!Bots::IsValidClientNum(clientNum))
|
|
||||||
{
|
|
||||||
Game::Scr_Error("^1botStop: Need to call on a player entity!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client->state < 3)
|
|
||||||
{
|
|
||||||
Game::Scr_Error("^1botStop: Needs to be connected.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!client->isBot)
|
if (!client->isBot)
|
||||||
{
|
{
|
||||||
Game::Scr_Error("^1botStop: Can only call on a bot!\n");
|
Game::Scr_Error("^1BotStop: Can only call on a bot!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_botai[clientNum] = { 0 };
|
g_botai[gentity->s.number] = {0};
|
||||||
g_botai[clientNum].weapon = 1;
|
g_botai[gentity->s.number].weapon = 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("botWeapon", [](Game::scr_entref_t id) // Usage: <bot> botWeapon(<str>);
|
Script::AddFunction("BotWeapon", [](Game::scr_entref_t id) // Usage: <bot> BotWeapon(<str>);
|
||||||
{
|
{
|
||||||
if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING)
|
if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||||
{
|
{
|
||||||
Game::Scr_Error("^1botWeapon: Needs one string parameter!\n");
|
Game::Scr_Error("^1BotWeapon: Needs one string parameter!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto weapon = Game::Scr_GetString(0);
|
const auto* weapon = Game::Scr_GetString(0);
|
||||||
|
|
||||||
Game::gentity_t* gentity = Script::getEntFromEntRef(id);
|
const auto* gentity = Script::GetEntFromEntRef(id);
|
||||||
Game::client_t* client = Script::getClientFromEnt(gentity);
|
const auto* client = Script::GetClientFromEnt(gentity);
|
||||||
unsigned int clientNum = GetClientNum(client);
|
|
||||||
|
|
||||||
if (!Bots::IsValidClientNum(clientNum))
|
|
||||||
{
|
|
||||||
Game::Scr_Error("^1botWeapon: Need to call on a player entity!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client->state < 3)
|
|
||||||
{
|
|
||||||
Game::Scr_Error("^1botWeapon: Needs to be connected.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!client->isBot)
|
if (!client->isBot)
|
||||||
{
|
{
|
||||||
Game::Scr_Error("^1botWeapon: Can only call on a bot!\n");
|
Game::Scr_Error("^1BotWeapon: Can only call on a bot!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (weapon == ""s)
|
if (weapon[0] == '\0')
|
||||||
{
|
{
|
||||||
g_botai[clientNum].weapon = 1;
|
g_botai[gentity->s.number].weapon = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int weapId = Game::G_GetWeaponIndexForName(weapon);
|
const auto weapId = Game::G_GetWeaponIndexForName(weapon);
|
||||||
|
g_botai[gentity->s.number].weapon = static_cast<uint16_t>(weapId);
|
||||||
g_botai[clientNum].weapon = (unsigned short)weapId;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("botAction", [](Game::scr_entref_t id) // Usage: <bot> botAction(<str action>);
|
Script::AddFunction("BotAction", [](Game::scr_entref_t id) // Usage: <bot> BotAction(<str action>);
|
||||||
{
|
{
|
||||||
if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING)
|
if (Game::Scr_GetNumParam() != 1u || Game::Scr_GetType(0) != Game::VAR_STRING)
|
||||||
{
|
{
|
||||||
Game::Scr_Error("^1botAction: Needs one string parameter!\n");
|
Game::Scr_Error("^1BotAction: Needs one string parameter!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto action = Game::Scr_GetString(0);
|
const auto* action = Game::Scr_GetString(0);
|
||||||
|
|
||||||
Game::gentity_t* gentity = Script::getEntFromEntRef(id);
|
const auto* gentity = Script::GetEntFromEntRef(id);
|
||||||
Game::client_t* client = Script::getClientFromEnt(gentity);
|
const auto* client = Script::GetClientFromEnt(gentity);
|
||||||
unsigned int clientNum = GetClientNum(client);
|
|
||||||
|
|
||||||
if (!Bots::IsValidClientNum(clientNum))
|
|
||||||
{
|
|
||||||
Game::Scr_Error("^1botAction: Need to call on a player entity!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client->state < 3)
|
|
||||||
{
|
|
||||||
Game::Scr_Error("^1botAction: Needs to be connected.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!client->isBot)
|
if (!client->isBot)
|
||||||
{
|
{
|
||||||
Game::Scr_Error("^1botAction: Can only call on a bot!\n");
|
Game::Scr_Error("^1BotAction: Can only call on a bot!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action[0] != '+' && action[0] != '-')
|
if (action[0] != '+' && action[0] != '-')
|
||||||
{
|
{
|
||||||
Game::Scr_Error("^1botAction: Sign for action must be '+' or '-'.\n");
|
Game::Scr_Error("^1BotAction: Sign for action must be '+' or '-'.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(BotActions) / sizeof(BotAction_t); ++i)
|
for (auto i = 0u; i < sizeof(BotActions) / sizeof(BotAction_t); ++i)
|
||||||
{
|
{
|
||||||
if (strcmp(&action[1], BotActions[i].action))
|
if (strcmp(&action[1], BotActions[i].action))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (action[0] == '+')
|
if (action[0] == '+')
|
||||||
g_botai[clientNum].buttons |= BotActions[i].key;
|
g_botai[gentity->s.number].buttons |= BotActions[i].key;
|
||||||
else
|
else
|
||||||
g_botai[clientNum].buttons &= ~(BotActions[i].key);
|
g_botai[gentity->s.number].buttons &= ~(BotActions[i].key);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::Scr_Error("^1botAction: Unknown action.\n");
|
Game::Scr_Error("^1BotAction: Unknown action.\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("botMovement", [](Game::scr_entref_t id) // Usage: <bot> botMovement(<int>, <int>);
|
Script::AddFunction("BotMovement", [](Game::scr_entref_t id) // Usage: <bot> BotMovement(<int>, <int>);
|
||||||
{
|
{
|
||||||
if (Game::Scr_GetNumParam() != 2u || Game::Scr_GetType(0) != Game::VAR_INTEGER || Game::Scr_GetType(1) != Game::VAR_INTEGER)
|
if (Game::Scr_GetNumParam() != 2u || Game::Scr_GetType(0) != Game::VAR_INTEGER || Game::Scr_GetType(1) != Game::VAR_INTEGER)
|
||||||
{
|
{
|
||||||
Game::Scr_Error("^1botMovement: Needs two integer parameters!\n");
|
Game::Scr_Error("^1BotMovement: Needs two integer parameters!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto forwardInt = Game::Scr_GetInt(0);
|
auto forwardInt = Game::Scr_GetInt(0);
|
||||||
auto rightInt = Game::Scr_GetInt(1);
|
auto rightInt = Game::Scr_GetInt(1);
|
||||||
|
|
||||||
Game::gentity_t* gentity = Script::getEntFromEntRef(id);
|
const auto* gentity = Script::GetEntFromEntRef(id);
|
||||||
Game::client_t* client = Script::getClientFromEnt(gentity);
|
const auto* client = Script::GetClientFromEnt(gentity);
|
||||||
unsigned int clientNum = GetClientNum(client);
|
|
||||||
|
|
||||||
if (!Bots::IsValidClientNum(clientNum))
|
|
||||||
{
|
|
||||||
Game::Scr_Error("^1botMovement: Need to call on a player entity!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client->state < 3)
|
|
||||||
{
|
|
||||||
Game::Scr_Error("^1botMovement: Needs to be connected.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!client->isBot)
|
if (!client->isBot)
|
||||||
{
|
{
|
||||||
Game::Scr_Error("^1botMovement: Can only call on a bot!\n");
|
Game::Scr_Error("^1BotMovement: Can only call on a bot!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (forwardInt > 127)
|
if (forwardInt > 127)
|
||||||
forwardInt = 127;
|
forwardInt = 127;
|
||||||
|
|
||||||
if (forwardInt < -127)
|
if (forwardInt < -127)
|
||||||
forwardInt = -127;
|
forwardInt = -127;
|
||||||
|
|
||||||
if (rightInt > 127)
|
if (rightInt > 127)
|
||||||
rightInt = 127;
|
rightInt = 127;
|
||||||
|
|
||||||
if (rightInt < -127)
|
if (rightInt < -127)
|
||||||
rightInt = -127;
|
rightInt = -127;
|
||||||
|
|
||||||
g_botai[clientNum].forward = (int8)forwardInt;
|
g_botai[gentity->s.number].forward = static_cast<int8_t>(forwardInt);
|
||||||
g_botai[clientNum].right = (int8)rightInt;
|
g_botai[gentity->s.number].right = static_cast<int8_t>(rightInt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,24 +314,22 @@ namespace Components
|
|||||||
Utils::Hook(0x627021, 0x4BB9B0, HOOK_CALL).install()->quick();
|
Utils::Hook(0x627021, 0x4BB9B0, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x627241, 0x4BB9B0, HOOK_CALL).install()->quick();
|
Utils::Hook(0x627241, 0x4BB9B0, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
// zero the bot command array
|
// Zero the bot command array
|
||||||
for (int i = 0; i < MAX_G_BOTAI_ENTRIES; i++)
|
for (auto i = 0; i < MAX_G_BOTAI_ENTRIES; i++)
|
||||||
{
|
{
|
||||||
g_botai[i] = { 0 };
|
g_botai[i] = {0};
|
||||||
g_botai[i].weapon = 1; // prevent the bots from defaulting to the 'none' weapon
|
g_botai[i].weapon = 1; // Prevent the bots from defaulting to the 'none' weapon
|
||||||
}
|
}
|
||||||
|
|
||||||
// have the bots perform the command every server frame
|
// Have the bots perform the command every server frame
|
||||||
Scheduler::OnFrame([]()
|
Scheduler::OnFrame([]()
|
||||||
{
|
{
|
||||||
if (!Game::SV_Loaded())
|
if (!Game::SV_Loaded())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int time = *Game::svs_time;
|
for (auto i = 0; i < *Game::svs_numclients; ++i)
|
||||||
int numClients = *Game::svs_numclients;
|
|
||||||
for (int i = 0; i < numClients; ++i)
|
|
||||||
{
|
{
|
||||||
Game::client_t* client = &Game::svs_clients[i];
|
auto* client = &Game::svs_clients[i];
|
||||||
|
|
||||||
if (client->state < 3)
|
if (client->state < 3)
|
||||||
continue;
|
continue;
|
||||||
@ -428,9 +337,9 @@ namespace Components
|
|||||||
if (!client->isBot)
|
if (!client->isBot)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Game::usercmd_s ucmd = { 0 };
|
Game::usercmd_s ucmd = {0};
|
||||||
|
|
||||||
ucmd.serverTime = time;
|
ucmd.serverTime = *Game::svs_time;
|
||||||
|
|
||||||
ucmd.buttons = g_botai[i].buttons;
|
ucmd.buttons = g_botai[i].buttons;
|
||||||
ucmd.forwardmove = g_botai[i].forward;
|
ucmd.forwardmove = g_botai[i].forward;
|
||||||
@ -445,15 +354,17 @@ namespace Components
|
|||||||
|
|
||||||
Command::Add("spawnBot", [](Command::Params* params)
|
Command::Add("spawnBot", [](Command::Params* params)
|
||||||
{
|
{
|
||||||
unsigned int count = 1;
|
auto count = 1;
|
||||||
|
|
||||||
if (params->length() > 1)
|
if (params->length() > 1)
|
||||||
{
|
{
|
||||||
if (params->get(1) == "all"s) count = static_cast<unsigned int>(-1);
|
if (params->get(1) == "all"s)
|
||||||
else count = atoi(params->get(1));
|
count = *Game::svs_numclients;
|
||||||
|
else
|
||||||
|
count = std::atoi(params->get(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
count = std::min(18u, count);
|
count = std::min(*Game::svs_numclients, count);
|
||||||
|
|
||||||
// Check if ingame and host
|
// Check if ingame and host
|
||||||
if (!Game::SV_Loaded())
|
if (!Game::SV_Loaded())
|
||||||
|
@ -7,7 +7,6 @@ namespace Components
|
|||||||
public:
|
public:
|
||||||
Bots();
|
Bots();
|
||||||
~Bots();
|
~Bots();
|
||||||
static unsigned int GetClientNum(Game::client_s*);
|
|
||||||
static bool IsValidClientNum(unsigned int);
|
static bool IsValidClientNum(unsigned int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -15,7 +14,7 @@ namespace Components
|
|||||||
|
|
||||||
static void BuildConnectString(char* buffer, const char* connectString, int num, int, int protocol, int checksum, int statVer, int statStuff, int port);
|
static void BuildConnectString(char* buffer, const char* connectString, int num, int, int protocol, int checksum, int statVer, int statStuff, int port);
|
||||||
|
|
||||||
static void Spawn(unsigned int count);
|
static void Spawn(int count);
|
||||||
|
|
||||||
static void AddMethods();
|
static void AddMethods();
|
||||||
};
|
};
|
||||||
|
@ -31,7 +31,7 @@ namespace Components
|
|||||||
if (mode != "append"s && mode != "write"s)
|
if (mode != "append"s && mode != "write"s)
|
||||||
{
|
{
|
||||||
Game::Com_Printf(0, "^3fileWrite: mode not defined or was wrong, defaulting to 'write'\n");
|
Game::Com_Printf(0, "^3fileWrite: mode not defined or was wrong, defaulting to 'write'\n");
|
||||||
mode = const_cast<char*>("write");
|
mode = "write";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == "write"s)
|
if (mode == "write"s)
|
||||||
@ -126,39 +126,25 @@ namespace Components
|
|||||||
void Client::AddMethods()
|
void Client::AddMethods()
|
||||||
{
|
{
|
||||||
// Client methods
|
// Client methods
|
||||||
|
Script::AddFunction("GetIp", [](Game::scr_entref_t id) // gsc: self GetIp()
|
||||||
Script::AddFunction("getIp", [](Game::scr_entref_t id) // gsc: self getIp()
|
|
||||||
{
|
{
|
||||||
Game::gentity_t* gentity = Script::getEntFromEntRef(id);
|
const auto* gentity = Script::GetEntFromEntRef(id);
|
||||||
Game::client_t* client = Script::getClientFromEnt(gentity);
|
const auto* client = Script::GetClientFromEnt(gentity);
|
||||||
|
|
||||||
if (client->state >= 3)
|
|
||||||
{
|
|
||||||
std::string ip = Game::NET_AdrToString(client->netchan.remoteAddress);
|
std::string ip = Game::NET_AdrToString(client->netchan.remoteAddress);
|
||||||
|
|
||||||
if (ip.find_first_of(":") != std::string::npos)
|
if (ip.find_first_of(":") != std::string::npos)
|
||||||
ip.erase(ip.begin() + ip.find_first_of(":"), ip.end()); // erase port
|
ip.erase(ip.begin() + ip.find_first_of(":"), ip.end()); // Erase port
|
||||||
|
|
||||||
Game::Scr_AddString(ip.data());
|
Game::Scr_AddString(ip.data());
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("getPing", [](Game::scr_entref_t id) // gsc: self getPing()
|
Script::AddFunction("GetPing", [](Game::scr_entref_t id) // gsc: self GetPing()
|
||||||
{
|
{
|
||||||
Game::gentity_t* gentity = Script::getEntFromEntRef(id);
|
const auto* gentity = Script::GetEntFromEntRef(id);
|
||||||
Game::client_t* client = Script::getClientFromEnt(gentity);
|
const auto* client = Script::GetClientFromEnt(gentity);
|
||||||
|
|
||||||
if (client->state >= 3)
|
Game::Scr_AddInt(client->ping);
|
||||||
{
|
|
||||||
int ping = (int)client->ping;
|
|
||||||
Game::Scr_AddInt(ping);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::AddCommands()
|
|
||||||
{
|
|
||||||
Command::Add("NULL", [](Command::Params*)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,11 +152,9 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Client::AddFunctions();
|
Client::AddFunctions();
|
||||||
Client::AddMethods();
|
Client::AddMethods();
|
||||||
Client::AddCommands();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Client::~Client()
|
Client::~Client()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,6 +12,5 @@ namespace Components
|
|||||||
|
|
||||||
static void AddFunctions();
|
static void AddFunctions();
|
||||||
static void AddMethods();
|
static void AddMethods();
|
||||||
static void AddCommands();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -142,9 +142,11 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Script::AddFunction("Noclip", [](Game::scr_entref_t entref) // gsc: Noclip(<optional int toggle>);
|
Script::AddFunction("Noclip", [](Game::scr_entref_t entref) // gsc: Noclip(<optional int toggle>);
|
||||||
{
|
{
|
||||||
if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr)
|
const auto* ent = Script::GetEntFromEntRef(entref);
|
||||||
|
|
||||||
|
if (ent->client == nullptr)
|
||||||
{
|
{
|
||||||
Game::Scr_Error(Utils::String::VA("^1NoClip: entity %u is not a client\n", entref));
|
Game::Scr_ObjectError(Utils::String::VA("^1NoClip: entity %u is not a client\n", entref));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,24 +154,26 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (Game::Scr_GetInt(0))
|
if (Game::Scr_GetInt(0))
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].client->flags |= Game::PLAYER_FLAG_NOCLIP;
|
ent->client->flags |= Game::PLAYER_FLAG_NOCLIP;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].client->flags &= ~Game::PLAYER_FLAG_NOCLIP;
|
ent->client->flags &= ~Game::PLAYER_FLAG_NOCLIP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_NOCLIP;
|
ent->client->flags ^= Game::PLAYER_FLAG_NOCLIP;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("Ufo", [](Game::scr_entref_t entref) // gsc: Ufo(<optional int toggle>);
|
Script::AddFunction("Ufo", [](Game::scr_entref_t entref) // gsc: Ufo(<optional int toggle>);
|
||||||
{
|
{
|
||||||
if (entref >= Game::MAX_GENTITIES || Game::g_entities[entref].client == nullptr)
|
const auto* ent = Script::GetEntFromEntRef(entref);
|
||||||
|
|
||||||
|
if (ent->client == nullptr)
|
||||||
{
|
{
|
||||||
Game::Scr_Error(Utils::String::VA("^1Ufo: entity %u is not a client\n", entref));
|
Game::Scr_ObjectError(Utils::String::VA("^1Ufo: entity %u is not a client\n", entref));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,91 +181,79 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (Game::Scr_GetInt(0))
|
if (Game::Scr_GetInt(0))
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].client->flags |= Game::PLAYER_FLAG_UFO;
|
ent->client->flags |= Game::PLAYER_FLAG_UFO;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].client->flags &= ~Game::PLAYER_FLAG_UFO;
|
ent->client->flags &= ~Game::PLAYER_FLAG_UFO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].client->flags ^= Game::PLAYER_FLAG_UFO;
|
ent->client->flags ^= Game::PLAYER_FLAG_UFO;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("God", [](Game::scr_entref_t entref) // gsc: God(<optional int toggle>);
|
Script::AddFunction("God", [](Game::scr_entref_t entref) // gsc: God(<optional int toggle>);
|
||||||
{
|
{
|
||||||
if (entref >= Game::MAX_GENTITIES)
|
auto* ent = Script::GetEntFromEntRef(entref);
|
||||||
{
|
|
||||||
Game::Scr_Error(Utils::String::VA("^1God: entity %u is out of bounds\n", entref));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER)
|
if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER)
|
||||||
{
|
{
|
||||||
if (Game::Scr_GetInt(0))
|
if (Game::Scr_GetInt(0))
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].flags |= Game::FL_GODMODE;
|
ent->flags |= Game::FL_GODMODE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].flags &= ~Game::FL_GODMODE;
|
ent->flags &= ~Game::FL_GODMODE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].flags ^= Game::FL_GODMODE;
|
ent->flags ^= Game::FL_GODMODE;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("Demigod", [](Game::scr_entref_t entref) // gsc: Demigod(<optional int toggle>);
|
Script::AddFunction("Demigod", [](Game::scr_entref_t entref) // gsc: Demigod(<optional int toggle>);
|
||||||
{
|
{
|
||||||
if (entref >= Game::MAX_GENTITIES)
|
auto* ent = Script::GetEntFromEntRef(entref);
|
||||||
{
|
|
||||||
Game::Scr_Error(Utils::String::VA("^1Demigod: entity %u is out of bounds\n", entref));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER)
|
if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER)
|
||||||
{
|
{
|
||||||
if (Game::Scr_GetInt(0))
|
if (Game::Scr_GetInt(0))
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].flags |= Game::FL_DEMI_GODMODE;
|
ent->flags |= Game::FL_DEMI_GODMODE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].flags &= ~Game::FL_DEMI_GODMODE;
|
ent->flags &= ~Game::FL_DEMI_GODMODE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].flags ^= Game::FL_DEMI_GODMODE;
|
ent->flags ^= Game::FL_DEMI_GODMODE;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Script::AddFunction("Notarget", [](Game::scr_entref_t entref) // gsc: Notarget(<optional int toggle>);
|
Script::AddFunction("Notarget", [](Game::scr_entref_t entref) // gsc: Notarget(<optional int toggle>);
|
||||||
{
|
{
|
||||||
if (entref >= Game::MAX_GENTITIES)
|
auto* ent = Script::GetEntFromEntRef(entref);
|
||||||
{
|
|
||||||
Game::Scr_Error(Utils::String::VA("^1Notarget: entity %u is out of bounds\n", entref));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER)
|
if (Game::Scr_GetNumParam() == 1u && Game::Scr_GetType(0) == Game::VAR_INTEGER)
|
||||||
{
|
{
|
||||||
if (Game::Scr_GetInt(0))
|
if (Game::Scr_GetInt(0))
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].flags |= Game::FL_NOTARGET;
|
ent->flags |= Game::FL_NOTARGET;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].flags &= ~Game::FL_NOTARGET;
|
ent->flags &= ~Game::FL_NOTARGET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game::g_entities[entref].flags ^= Game::FL_NOTARGET;
|
ent->flags ^= Game::FL_NOTARGET;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -487,18 +487,25 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::gentity_t* Script::getEntFromEntRef(Game::scr_entref_t entref)
|
Game::gentity_t* Script::GetEntFromEntRef(const Game::scr_entref_t entref)
|
||||||
{
|
{
|
||||||
Game::gentity_t* gentity = &Game::g_entities[entref];
|
if (entref >= Game::MAX_GENTITIES)
|
||||||
return gentity;
|
{
|
||||||
|
Game::Scr_ObjectError("Not an entity");
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::client_t* Script::getClientFromEnt(Game::gentity_t* gentity)
|
return &Game::g_entities[entref];
|
||||||
{
|
|
||||||
if (!gentity->client)
|
|
||||||
{
|
|
||||||
Logger::Error(Game::ERR_SCRIPT_DROP, "Entity: %i is not a client", gentity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Game::client_t* Script::GetClientFromEnt(const Game::gentity_t* gentity)
|
||||||
|
{
|
||||||
|
if (gentity->client == nullptr)
|
||||||
|
{
|
||||||
|
Game::Scr_ObjectError(Utils::String::VA("Entity %i is not a player", gentity->s.number));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return &Game::svs_clients[gentity->s.number];
|
return &Game::svs_clients[gentity->s.number];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,7 +551,7 @@ namespace Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto str = Game::Scr_GetString(0);
|
const auto str = Game::Scr_GetString(0);
|
||||||
|
|
||||||
Game::Com_Printf(0, str);
|
Game::Com_Printf(0, str);
|
||||||
});
|
});
|
||||||
@ -558,7 +565,7 @@ namespace Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto str = Game::Scr_GetString(0);
|
const auto str = Game::Scr_GetString(0);
|
||||||
|
|
||||||
Command::Execute(str, false);
|
Command::Execute(str, false);
|
||||||
});
|
});
|
||||||
|
@ -29,8 +29,8 @@ namespace Components
|
|||||||
|
|
||||||
static void OnVMShutdown(Utils::Slot<Scheduler::Callback> callback);
|
static void OnVMShutdown(Utils::Slot<Scheduler::Callback> callback);
|
||||||
|
|
||||||
static Game::gentity_t* getEntFromEntRef(Game::scr_entref_t entref);
|
static Game::gentity_t* GetEntFromEntRef(const Game::scr_entref_t entref);
|
||||||
static Game::client_t* getClientFromEnt(Game::gentity_t* gentity);
|
static Game::client_t* GetClientFromEnt(const Game::gentity_t* gentity);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::string ScriptName;
|
static std::string ScriptName;
|
||||||
|
@ -274,6 +274,7 @@ namespace Game
|
|||||||
Scr_Notify_t Scr_Notify = Scr_Notify_t(0x4A4750);
|
Scr_Notify_t Scr_Notify = Scr_Notify_t(0x4A4750);
|
||||||
Scr_NotifyLevel_t Scr_NotifyLevel = Scr_NotifyLevel_t(0x4D9C30);
|
Scr_NotifyLevel_t Scr_NotifyLevel = Scr_NotifyLevel_t(0x4D9C30);
|
||||||
Scr_Error_t Scr_Error = Scr_Error_t(0x61E8B0);
|
Scr_Error_t Scr_Error = Scr_Error_t(0x61E8B0);
|
||||||
|
Scr_ObjectError_t Scr_ObjectError = Scr_ObjectError_t(0x42EF40);
|
||||||
Scr_GetType_t Scr_GetType = Scr_GetType_t(0x422900);
|
Scr_GetType_t Scr_GetType = Scr_GetType_t(0x422900);
|
||||||
|
|
||||||
Scr_ClearOutParams_t Scr_ClearOutParams = Scr_ClearOutParams_t(0x4386E0);
|
Scr_ClearOutParams_t Scr_ClearOutParams = Scr_ClearOutParams_t(0x4386E0);
|
||||||
|
@ -365,7 +365,7 @@ namespace Game
|
|||||||
typedef int(__cdecl* FS_Delete_t)(const char* fileName);
|
typedef int(__cdecl* FS_Delete_t)(const char* fileName);
|
||||||
extern FS_Delete_t FS_Delete;
|
extern FS_Delete_t FS_Delete;
|
||||||
|
|
||||||
typedef int(__cdecl* G_GetWeaponIndexForName_t)(char*);
|
typedef unsigned int(__cdecl * G_GetWeaponIndexForName_t)(const char*);
|
||||||
extern G_GetWeaponIndexForName_t G_GetWeaponIndexForName;
|
extern G_GetWeaponIndexForName_t G_GetWeaponIndexForName;
|
||||||
|
|
||||||
typedef void(__cdecl* G_SpawnEntitiesFromString_t)();
|
typedef void(__cdecl* G_SpawnEntitiesFromString_t)();
|
||||||
@ -657,16 +657,16 @@ namespace Game
|
|||||||
typedef int(__cdecl * Scr_LoadScript_t)(const char*);
|
typedef int(__cdecl * Scr_LoadScript_t)(const char*);
|
||||||
extern Scr_LoadScript_t Scr_LoadScript;
|
extern Scr_LoadScript_t Scr_LoadScript;
|
||||||
|
|
||||||
typedef char* (__cdecl * Scr_GetString_t)(int);
|
typedef const char*(__cdecl * Scr_GetString_t)(unsigned int);
|
||||||
extern Scr_GetString_t Scr_GetString;
|
extern Scr_GetString_t Scr_GetString;
|
||||||
|
|
||||||
typedef float(__cdecl * Scr_GetFloat_t)(int);
|
typedef float(__cdecl * Scr_GetFloat_t)(unsigned int);
|
||||||
extern Scr_GetFloat_t Scr_GetFloat;
|
extern Scr_GetFloat_t Scr_GetFloat;
|
||||||
|
|
||||||
typedef int(__cdecl * Scr_GetInt_t)(int);
|
typedef int(__cdecl * Scr_GetInt_t)(unsigned int);
|
||||||
extern Scr_GetInt_t Scr_GetInt;
|
extern Scr_GetInt_t Scr_GetInt;
|
||||||
|
|
||||||
typedef unsigned int(__cdecl * Scr_GetObject_t)(int);
|
typedef unsigned int(__cdecl * Scr_GetObject_t)(unsigned int);
|
||||||
extern Scr_GetObject_t Scr_GetObject;
|
extern Scr_GetObject_t Scr_GetObject;
|
||||||
|
|
||||||
typedef unsigned int(__cdecl * Scr_GetNumParam_t)();
|
typedef unsigned int(__cdecl * Scr_GetNumParam_t)();
|
||||||
@ -696,12 +696,15 @@ namespace Game
|
|||||||
typedef bool(__cdecl * Scr_IsSystemActive_t)();
|
typedef bool(__cdecl * Scr_IsSystemActive_t)();
|
||||||
extern Scr_IsSystemActive_t Scr_IsSystemActive;
|
extern Scr_IsSystemActive_t Scr_IsSystemActive;
|
||||||
|
|
||||||
typedef int(__cdecl* Scr_GetType_t)(unsigned int);
|
typedef int(__cdecl * Scr_GetType_t)(unsigned int);
|
||||||
extern Scr_GetType_t Scr_GetType;
|
extern Scr_GetType_t Scr_GetType;
|
||||||
|
|
||||||
typedef void(__cdecl* Scr_Error_t)(const char*);
|
typedef void(__cdecl * Scr_Error_t)(const char*);
|
||||||
extern Scr_Error_t Scr_Error;
|
extern Scr_Error_t Scr_Error;
|
||||||
|
|
||||||
|
typedef void(__cdecl * Scr_ObjectError_t)(const char*);
|
||||||
|
extern Scr_ObjectError_t Scr_ObjectError;
|
||||||
|
|
||||||
typedef script_t* (__cdecl * Script_Alloc_t)(int length);
|
typedef script_t* (__cdecl * Script_Alloc_t)(int length);
|
||||||
extern Script_Alloc_t Script_Alloc;
|
extern Script_Alloc_t Script_Alloc;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user