Add CritSay and improve a few DominateSay things

This commit is contained in:
LightCat 2019-01-25 21:31:45 +01:00
parent 9b30faa9ff
commit 26ba1b6b1b
6 changed files with 164 additions and 10 deletions

5
data/critsay.txt Normal file
View File

@ -0,0 +1,5 @@
Woops, sorry for that crit %name%
crandom rits are fair and balanced
gamer team %team%
ok now this is epic, %name%
crits are balanced

View File

@ -1,11 +1,5 @@
replace this file with actual dominatesay.
usable macros:
%team% %class% %killer% %name% %myteam% %myclass% %dominum% \n
examples:
%name% is getting dominated. no big surprise. %name% is getting dominated. no big surprise.
%team% actually sucks i already have %dominum% dominations wtf? %team% sucks giant dick, already have %dominum% dominations.
%name%, quit playing %class% dude. i'm already dominating you. %name%, quit playing %class% dude. i'm already dominating you.
lmao adding %name% to my list of idiots lmao adding %name% to my list of idiots
%dominum% dominations lol %dominum% dominations lol

View File

@ -71,6 +71,15 @@
<Option name="Lithium" value="7"/> <Option name="Lithium" value="7"/>
</Select> </Select>
</LabeledObject> </LabeledObject>
<AutoVariable width="fill" target="critsay.file" label="Critsay file"/>
<LabeledObject width="fill" label="Critsay Mode">
<Select target="critsay.mode">
<Option name="Disable" value="0"/>
<Option name="Custom" value="1"/>
<Option name="Default" value="2"/>
</Select>
</LabeledObject>
<AutoVariable width="fill" target="critsay.delay" label="Critsay Delay"/>
</List> </List>
</Box> </Box>
</Tab> </Tab>

View File

@ -22,6 +22,7 @@ target_sources(cathook PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/AutoTaunt.cpp" "${CMAKE_CURRENT_LIST_DIR}/AutoTaunt.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Bunnyhop.cpp" "${CMAKE_CURRENT_LIST_DIR}/Bunnyhop.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Backtrack.cpp" "${CMAKE_CURRENT_LIST_DIR}/Backtrack.cpp"
"${CMAKE_CURRENT_LIST_DIR}/CritSay.cpp"
"${CMAKE_CURRENT_LIST_DIR}/FollowBot.cpp" "${CMAKE_CURRENT_LIST_DIR}/FollowBot.cpp"
"${CMAKE_CURRENT_LIST_DIR}/KillSay.cpp" "${CMAKE_CURRENT_LIST_DIR}/KillSay.cpp"
"${CMAKE_CURRENT_LIST_DIR}/DominateSay.cpp" "${CMAKE_CURRENT_LIST_DIR}/DominateSay.cpp"

144
src/hacks/CritSay.cpp Normal file
View File

@ -0,0 +1,144 @@
/*
* Created on 25.01.2019 By BenCat07
* CritSay.cpp
* Read if gay
*/
#include <settings/Int.hpp>
#include "common.hpp"
static settings::Int critsay_mode{ "critsay.mode", "0" };
static settings::String filename{ "critsay.file", "critsay.txt" };
static settings::Int delay{ "critsay.delay", "100" };
struct CritsayStorage
{
Timer timer{};
unsigned delay{};
std::string message{};
};
static std::unordered_map<int, CritsayStorage> critsay_storage{};
namespace hacks::shared::critsay
{
// Thanks HellJustFroze for linking me http://daviseford.com/shittalk/
const std::vector<std::string> builtin_default = { "Woops, i slipped", "*critical hit* -> %name%", "ok now let's do it again, %name%", "nice" };
const std::string tf_classes_killsay[] = { "class", "scout", "sniper", "soldier", "demoman", "medic", "heavy", "pyro", "spy", "engineer" };
const std::string tf_teams_killsay[] = { "RED", "BLU" };
static std::string lastmsg{};
TextFile file{};
std::string ComposeCritSay(IGameEvent *event)
{
const std::vector<std::string> *source = nullptr;
switch (*critsay_mode)
{
case 1:
source = &file.lines;
break;
case 2:
source = &builtin_default;
break;
default:
break;
}
if (!source || source->empty())
return "";
if (!event)
return "";
if (!(event->GetInt("damagebits", 0) & (1 << 20)))
return "";
int vid = event->GetInt("userid");
int kid = event->GetInt("attacker");
if (kid == vid)
return "";
if (g_IEngine->GetPlayerForUserID(kid) != g_IEngine->GetLocalPlayer())
return "";
std::string msg = source->at(rand() % source->size());
// checks if the killsays.txt file is not 1 line. 100% sure it's going
// to crash if it is.
while (msg == lastmsg && source->size() > 1)
msg = source->at(rand() % source->size());
lastmsg = msg;
player_info_s info{};
g_IEngine->GetPlayerInfo(g_IEngine->GetPlayerForUserID(vid), &info);
ReplaceSpecials(msg);
CachedEntity *ent = ENTITY(g_IEngine->GetPlayerForUserID(vid));
int clz = g_pPlayerResource->GetClass(ent);
ReplaceString(msg, "%class%", tf_classes_killsay[clz]);
player_info_s infok{};
g_IEngine->GetPlayerInfo(g_IEngine->GetPlayerForUserID(kid), &infok);
ReplaceString(msg, "%killer%", std::string(infok.name));
ReplaceString(msg, "%team%", tf_teams_killsay[ent->m_iTeam() - 2]);
ReplaceString(msg, "%myteam%", tf_teams_killsay[LOCAL_E->m_iTeam() - 2]);
ReplaceString(msg, "%myclass%", tf_classes_killsay[g_pPlayerResource->GetClass(LOCAL_E)]);
ReplaceString(msg, "%name%", std::string(info.name));
return msg;
}
class CritSayEventListener : public IGameEventListener2
{
void FireGameEvent(IGameEvent *event) override
{
if (!critsay_mode)
return;
std::string message = hacks::shared::critsay::ComposeCritSay(event);
if (!message.empty())
{
int vid = event->GetInt("userid");
critsay_storage[vid].delay = *delay;
critsay_storage[vid].timer.update();
critsay_storage[vid].message = message;
}
}
};
static void ProcessCritsay()
{
if (critsay_storage.empty())
return;
for (auto &i : critsay_storage)
{
if (i.second.message.empty())
continue;
if (i.second.timer.test_and_set(i.second.delay))
{
chat_stack::Say(i.second.message, false);
i.second = {};
}
}
}
static CritSayEventListener listener{};
void reload()
{
file.Load(*filename);
}
static CatCommand reload_command("critsay_reload", "Reload critsays", []() { reload(); });
void init()
{
g_IEventManager2->AddListener(&listener, (const char *) "player_death", false);
}
void shutdown()
{
g_IEventManager2->RemoveListener(&listener);
}
static InitRoutine runinit([]() {
EC::Register(EC::Paint, ProcessCritsay, "paint_critsay", EC::average);
EC::Register(EC::Shutdown, shutdown, "shutdown_critsay", EC::average);
critsay_mode.installChangeCallback([](settings::VariableBase<int> &a, int value) {
if (value == 1)
reload();
});
init();
});
} // namespace hacks::shared::critsay

View File

@ -15,8 +15,9 @@ namespace hacks::shared::dominatesay
// a much better default dominatesay would be appreciated. // a much better default dominatesay would be appreciated.
const std::vector<std::string> builtin_default = { const std::vector<std::string> builtin_default = {
"dominating %name%! (%dominum% dominations)", "dominating %name%! (%dominum% dominations)",
"%name%, getting tapped?", "%name%, nice skill, you sell?",
"%killer% is dominating the server with %dominum% dominations!", "%name%, umad?",
"smh i have %dominum% dominations",
}; };
const std::string tf_classes_dominatesay[] = { "class", "scout", "sniper", "soldier", "demoman", "medic", "heavy", "pyro", "spy", "engineer" }; const std::string tf_classes_dominatesay[] = { "class", "scout", "sniper", "soldier", "demoman", "medic", "heavy", "pyro", "spy", "engineer" };
const std::string tf_teams_dominatesay[] = { "RED", "BLU" }; const std::string tf_teams_dominatesay[] = { "RED", "BLU" };