CSpeakModifiers: Difference between revisions
No edit summary |
Thunder4ik (talk | contribs) m (clean up, added deadend tag) |
||
(4 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{{Multiple issues| | |||
{{Dead end|date=January 2024}} | |||
{{orphan}} | |||
}} | |||
== Problem == | == Problem == | ||
Line 9: | Line 14: | ||
Here is the code for the class. | Here is the code for the class. | ||
< | <source lang=cpp> | ||
//====================== Written By PVKII Team ========================= | |||
// | |||
// Purpose: Utility class to simplify Speak calls with modifiers | |||
// | |||
// $NoKeywords: $ | |||
//======================================================================= | |||
class CSpeakModifiers | class CSpeakModifiers | ||
{ | { | ||
Line 33: | Line 44: | ||
CUtlVector<modifierentry> m_Modifiers; | CUtlVector<modifierentry> m_Modifiers; | ||
};</ | };</source> | ||
< | <source lang=cpp> | ||
/*********************************************** | /*********************************************** | ||
Line 81: | Line 92: | ||
Q_strncat(buffer,UTIL_VarArgs("%s:%s",m_Modifiers[m_Modifiers.Count() - 1].strKeyName,m_Modifiers[m_Modifiers.Count() - 1].strKeyValue),bufsize); | Q_strncat(buffer,UTIL_VarArgs("%s:%s",m_Modifiers[m_Modifiers.Count() - 1].strKeyName,m_Modifiers[m_Modifiers.Count() - 1].strKeyValue),bufsize); | ||
}</ | }</source> | ||
And here would be the overridden SpeakIfAllowed function you would use in conjunction with the utility class | And here would be the overridden SpeakIfAllowed function you would use in conjunction with the utility class | ||
< | <source lang=cpp> | ||
bool SpeakConceptIfAllowed( int iConcept, CSpeakModifiers *modifiers = NULL, bool bCanSpeakDead = false, bool bCanSpeakIfSpeaking = false, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL );</ | bool SpeakConceptIfAllowed( int iConcept, CSpeakModifiers *modifiers = NULL, bool bCanSpeakDead = false, bool bCanSpeakIfSpeaking = false, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL );</source> | ||
< | <source lang=cpp> | ||
bool CPVK2ChoreographyProperty::SpeakConceptIfAllowed( int iConcept, CSpeakModifiers *modifiers, bool bCanSpeakDead, bool bCanSpeakIfSpeaking, char *pszOutResponseChosen, size_t bufsize, IRecipientFilter *filter ) | bool CPVK2ChoreographyProperty::SpeakConceptIfAllowed( int iConcept, CSpeakModifiers *modifiers, bool bCanSpeakDead, bool bCanSpeakIfSpeaking, char *pszOutResponseChosen, size_t bufsize, IRecipientFilter *filter ) | ||
{ | { | ||
Line 99: | Line 110: | ||
else | else | ||
return GetOuter()->SpeakConceptIfAllowed(iConcept,NULL,bCanSpeakDead,bCanSpeakIfSpeaking,pszOutResponseChosen,bufsize,filter); | return GetOuter()->SpeakConceptIfAllowed(iConcept,NULL,bCanSpeakDead,bCanSpeakIfSpeaking,pszOutResponseChosen,bufsize,filter); | ||
}</ | }</source> | ||
And finally here is an example of the class being used | And finally here is an example of the class being used | ||
< | <source lang=cpp> | ||
if(pPlayerAttacker) | if(pPlayerAttacker) | ||
{ | { | ||
Line 123: | Line 134: | ||
pPlayerAttacker->ChoreoProp()->SpeakConceptIfAllowed( MP_CONCEPT_KILLED, &modifiers ); | pPlayerAttacker->ChoreoProp()->SpeakConceptIfAllowed( MP_CONCEPT_KILLED, &modifiers ); | ||
}</ | }</source> | ||
[[Category:Programming]] | |||
[[Category:Free source code]] |
Latest revision as of 08:50, 21 January 2024




January 2024

You can help by

Problem
If you have had to use the Response Rules system with modifiers passed in at a response request time you will be aware that you must spend your time concatenating strings to build these modifiers to pass into the Speak calls. It is time consuming to always write and just annoying to write.
Solution
In light of this problem I decided to write a simple utility class which would handle the dirty work for me. It is very small class and allows you to just pop in your modifiers whatever order you wish and it will build the output string for the response rules for you. It also takes in parameters as floating point numbers or integer numbers and converts them to strings for you.
Here is the code for the class.
//====================== Written By PVKII Team =========================
//
// Purpose: Utility class to simplify Speak calls with modifiers
//
// $NoKeywords: $
//=======================================================================
class CSpeakModifiers
{
DECLARE_CLASS_NOBASE( CSpeakModifiers );
public:
void AddModifier( const char *keyName, const char *keyValue );
void AddModifier( const char *keyName, int keyValue );
void AddModifier( const char *keyName, float keyValue );
void GetModifiersAsString(char *buffer, size_t bufsize);
protected:
struct modifierentry
{
modifierentry()
{
Q_memset(strKeyName,0,sizeof(strKeyName));
Q_memset(strKeyValue,0,sizeof(strKeyValue));
}
char strKeyName[128];
char strKeyValue[128];
};
CUtlVector<modifierentry> m_Modifiers;
};
/***********************************************
Speak Modifiers Utility Class
***********************************************/
void CSpeakModifiers::AddModifier(const char *keyName, const char *keyValue)
{
modifierentry m;
Q_strncpy(m.strKeyName,keyName,sizeof(m.strKeyName));
Q_strncpy(m.strKeyValue,keyValue,sizeof(m.strKeyValue));
m_Modifiers.AddToTail(m);
}
void CSpeakModifiers::AddModifier(const char *keyName, float keyValue)
{
modifierentry m;
Q_strncpy(m.strKeyName,keyName,sizeof(m.strKeyName));
Q_snprintf(m.strKeyValue,sizeof(m.strKeyValue),"%f",keyValue);
m_Modifiers.AddToTail(m);
}
void CSpeakModifiers::AddModifier(const char *keyName, int keyValue)
{
modifierentry m;
Q_strncpy(m.strKeyName,keyName,sizeof(m.strKeyName));
Q_snprintf(m.strKeyValue,sizeof(m.strKeyValue),"%d",keyValue);
m_Modifiers.AddToTail(m);
}
void CSpeakModifiers::GetModifiersAsString( char *buffer, size_t bufsize )
{
Q_memset(buffer,0,bufsize);
for(int i = 0; i < m_Modifiers.Count() - 1; i++)
{
Q_strncat(buffer,UTIL_VarArgs("%s:%s,",m_Modifiers[i].strKeyName,m_Modifiers[i].strKeyValue),bufsize);
}
Q_strncat(buffer,UTIL_VarArgs("%s:%s",m_Modifiers[m_Modifiers.Count() - 1].strKeyName,m_Modifiers[m_Modifiers.Count() - 1].strKeyValue),bufsize);
}
And here would be the overridden SpeakIfAllowed function you would use in conjunction with the utility class
bool SpeakConceptIfAllowed( int iConcept, CSpeakModifiers *modifiers = NULL, bool bCanSpeakDead = false, bool bCanSpeakIfSpeaking = false, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL );
bool CPVK2ChoreographyProperty::SpeakConceptIfAllowed( int iConcept, CSpeakModifiers *modifiers, bool bCanSpeakDead, bool bCanSpeakIfSpeaking, char *pszOutResponseChosen, size_t bufsize, IRecipientFilter *filter )
{
if(modifiers)
{
char modbuf[512];
modifiers->GetModifiersAsString(modbuf,sizeof(modbuf));
return GetOuter()->SpeakConceptIfAllowed(iConcept,modbuf,bCanSpeakDead,bCanSpeakIfSpeaking,pszOutResponseChosen,bufsize,filter);
}
else
return GetOuter()->SpeakConceptIfAllowed(iConcept,NULL,bCanSpeakDead,bCanSpeakIfSpeaking,pszOutResponseChosen,bufsize,filter);
}
And finally here is an example of the class being used
if(pPlayerAttacker)
{
CSpeakModifiers modifiers;
int nemesis_index = pPlayerAttacker->m_playerNemesis.Find(this);
if(nemesis_index != pPlayerAttacker->m_playerNemesis.InvalidIndex())
modifiers.AddModifier("revenge","true");
CBasePVK2BludgeonWeapon *pMelee = dynamic_cast<CBasePVK2BludgeonWeapon *>(subinfo.GetInflictor());
if(pMelee)
modifiers.AddModifier("attackdirection",pMelee->GetAttackDir() + 1);
if(subinfo.GetInflictor() && ( FClassnameIs(subinfo.GetInflictor(),"powderkeg") ||FClassnameIs(subinfo.GetInflictor(),"weapon_powderkeg") || FClassnameIs(subinfo.GetInflictor(),"weapon_chest") ))
modifiers.AddModifier("killweapon",subinfo.GetInflictor()->GetClassname());
modifiers.AddModifier("victimteam",GetTeamNumber());
modifiers.AddModifier("victimclass",GetPlayerClass() + 1);
pPlayerAttacker->ChoreoProp()->SpeakConceptIfAllowed( MP_CONCEPT_KILLED, &modifiers );
}