• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Feature Combo bot auto detector (beta)

Gesior.pl

Mega Noob&LOL 2012
Senator
Joined
Sep 18, 2007
Messages
2,951
Solutions
98
Reaction score
3,344
Location
Poland
GitHub
gesior
Script should work with TFS 0.3.4/0.3.5 (tested on 0.3.4pl2).
It broadcast msg like:
14:57 , Cfaniack, Vetrino, Lubie Chodzic Na Obcasie - did combo!
14:58 , Niegrzeczny, Gzresiek, Van Master Aka Loffciam Olcie - did combo!
15:01 , Yawner Thug, Isee, Killian - did combo!
and show animation in game.

Default config:
comboTime = 100 -- check sds in last 0.1 sec
comboMembers = 2 -- show animation (if animation = 1) when 2 or more players do combo
comboFriends = 3 -- save uid of players as 'friends' when more then 3 players do combo / broadcast nicks of players when 3 or more 'friends' do combo more then one time
comboFriendsClearTime = 5 * 60 * 1000 -- remove 'friend' from player 'friends' list when he didnt do combo for 5 minutes
comboFriendsClearInterval = 1 * 60 * 1000 -- remove 'old' 'friends' every minute
comboShowAnimation = 1 -- show animation on target/attackers and text "COMBO X" (x - number of combo players)

Under (spells.cpp) [add in valid place! check 'if(result)']:
PHP:
if(result)
	{
		Spell::postCastSpell(player);
Add:
PHP:
		if(item->getID() == 2268 && creatureId)
        {
            // check combos in last XX miliseconds
    		uint32_t time = OTSYS_TIME();
            AttackersMap tmpAttackersMap;
            AttackersMap tmpAttackersMap2;
            uint32_t comboTime = g_config.getNumber(ConfigManager::COMBO_CT);
            uint32_t comboMembers = g_config.getNumber(ConfigManager::COMBO_CM);
            uint32_t comboFriends = g_config.getNumber(ConfigManager::COMBO_CF);
            uint32_t comboFriendsClearTime = g_config.getNumber(ConfigManager::COMBO_FCT);
            uint32_t comboFriendsClearInterval = g_config.getNumber(ConfigManager::COMBO_FCI);
            uint32_t comboShowAnim = g_config.getNumber(ConfigManager::COMBO_SA);
            // remove old friends from list
            if(comboTime && comboFriends && time - comboFriendsListLastClear >= comboFriendsClearInterval)
            {
                    for(ComboFriendsList::iterator cflit = comboFriendsList.begin(); cflit != comboFriendsList.end(); ++cflit)
                            for(AttackersMap::iterator rfit = cflit->second.begin(); rfit != cflit->second.end(); ++rfit)
                                    if(rfit->second < time - comboFriendsClearTime)
                                            cflit->second.erase(rfit->first);
            }
    		if(comboTime && comboMembers && time - comboLastCheck >= comboTime)
    		{
                    for(AttackersMap::iterator acit = comboAttackersCount.begin(); acit != comboAttackersCount.end(); ++acit)
                    {
                              if(acit->second >= comboMembers)
                              {
                                          // make combo members list
                                          for(AttackersMap::iterator alit = comboAttackersList.begin(); alit != comboAttackersList.end(); ++alit)
                                          {
                                                  if(alit->second == acit->first)
                                                  {
                                                            comboList[alit->first] = alit->first;
                                                  }
                                          }
                                          // show combo animations
                                          if(comboShowAnim)
                                          {
                                                  Creature* creature = g_game.getCreatureByID(acit->first);
                                                  if(creature != NULL)
                                                  {
                                                        char buffer[20];
                                            			sprintf(buffer, "COMBO %d", acit->second);
                                            			g_game.addMagicEffect(creature->getPosition(), NM_ME_STUN);
                                            			g_game.addAnimatedText(creature->getPosition(), TEXTCOLOR_GREEN, buffer);
                                                  }
                                                  for(AttackersMap::iterator sait = comboList.begin(); sait != comboList.end(); ++sait)
                                                  {
                                                        Creature* creature = g_game.getCreatureByID(sait->first);
                                                        if(creature != NULL)
                                                        {
                                                              g_game.addMagicEffect(creature->getPosition(), NM_ME_CAKE);
                                                        }
                                                  }
                                          }
                                          comboFriendsNumber = 0;
                                          // make friends list
                                          for(AttackersMap::iterator cit = comboList.begin(); cit != comboList.end(); ++cit)
                                          {
                                                    if(comboFriendsList.find(cit->first) != comboFriendsList.end())
                                                    {
                                                              tmpAttackersMap2 = comboFriendsList[cit->first];
                                                              for(AttackersMap::iterator tait = tmpAttackersMap2.begin(); tait != tmpAttackersMap2.end(); ++tait)
                                                                        tmpAttackersMap[tait->first] = tait->first;
                                                    }
                                          }
                                          for(AttackersMap::iterator ccit = tmpAttackersMap.begin(); ccit != tmpAttackersMap.end(); ++ccit)
                                                    if(comboList.find(ccit->first) != comboList.end())
                                                              ++comboFriendsNumber;
                                          // broadcast combo members
                                          if(comboFriendsNumber >= comboFriends)
                                          {
                                                    std::stringstream comboNamesList;
                                              for(AttackersMap::iterator ccit2 = tmpAttackersMap.begin(); ccit2 != tmpAttackersMap.end(); ++ccit2)
                                                        if(comboList.find(ccit2->first) != comboList.end())
                                                        {
                                                                  Creature* creature = g_game.getCreatureByID(ccit2->first);
                                                                  if(creature != NULL)
                                                                            comboNamesList << ", " << creature->getName();
                                                        }
                                              comboNamesList << " - did combo!";
                                              g_game.broadcastMessage(comboNamesList.str(), MSG_STATUS_WARNING);
                                              // add new 'friends'
                                              for(AttackersMap::iterator cit = comboList.begin(); cit != comboList.end(); ++cit)
                                              {
                                                        tmpAttackersMap.clear();
                                                        if(comboFriendsList.find(cit->first) != comboFriendsList.end())
                                                                  tmpAttackersMap = comboFriendsList[cit->first];
                                                        for(AttackersMap::iterator tcit = comboList.begin(); tcit != comboList.end(); ++tcit)
                                                        {
                                                                  tmpAttackersMap[tcit->first] = time;
                                                        }
                                                        comboFriendsList[cit->first] = tmpAttackersMap;
                                                        
                                              }
                                          }
                                          comboList.clear();
                              }    
                    }
                    comboAttackersList.clear();
                    comboAttackersCount.clear();
                    comboLastCheck = time;
    		}
    		// add player to attackers list
            comboAttackersList[player->getID()] = creatureId;
            comboAttackersCount[creatureId] += 1;
        }
Under (spells.h):
PHP:
RuneSpellFunction* function;
Add:
PHP:
		typedef std::map<uint32_t, uint32_t> AttackersMap;
		AttackersMap comboAttackersList;
		AttackersMap comboAttackersCount;
		AttackersMap comboList;

		typedef std::map<uint32_t, AttackersMap> ComboFriendsList;
		ComboFriendsList comboFriendsList;
		
		uint32_t comboLastCheck;
		uint32_t comboFriendsNumber;
		uint32_t comboFriendsListLastClear;
Under (configmanager.cpp):
PHP:
m_confNumber[MAXIMUM_DOOR_LEVEL] = getGlobalNumber("maximumDoorLevel", 500);
Add:
PHP:
	m_confNumber[COMBO_CT] = getGlobalNumber("comboTime", 0);
	m_confNumber[COMBO_CM] = getGlobalNumber("comboMembers", 0);
	m_confNumber[COMBO_CF] = getGlobalNumber("comboFriends", 0);
	m_confNumber[COMBO_FCT] = getGlobalNumber("comboFriendsClearTime", 0);
	m_confNumber[COMBO_FCI] = getGlobalNumber("comboFriendsClearInterval", 0);
	m_confNumber[COMBO_SA] = getGlobalNumber("comboShowAnimation", 0);
Under (configmanager.h):
PHP:
MAXIMUM_DOOR_LEVEL,
Add:
PHP:
			COMBO_CT,
			COMBO_CM,
			COMBO_CF,
			COMBO_FCT,
			COMBO_FCI,
			COMBO_SA,
In config.lua add:
PHP:
	comboTime = 100
	comboMembers = 2
	comboFriends = 3
	comboFriendsClearTime = 5 * 60 * 1000
	comboFriendsClearInterval = 1 * 60 * 1000
	comboShowAnimation = 1

ITS BETA. I'LL OPTIMIZE CODE AND POST NEW VERSION.
EDIT:
(I use this version on my war ots with 150 online and 2GHz cpu, cpu use is under 30%)
 
Last edited:
i'dont understand

what is spells.cpp and the others. in folder of the server?
 
What if it's a planned combo and not bot? I mean, if me and my 3 friends make a at-once-click combo (meaning, we count down or something to shot at once). It's not impossible that we'd shoot that fast.
 
one problem. players were explaining if your in war and someone puts up an mwall the team is holding down sd key...when it disappear SDs gonna fly at same time.
 
one problem. players were explaining if your in war and someone puts up an mwall the team is holding down sd key...when it disappear SDs gonna fly at same time.

agree... dosnt rly work, i guess?
 
one problem. players were explaining if your in war and someone puts up an mwall the team is holding down sd key...when it disappear SDs gonna fly at same time.

That's the kinda stuff I meant :p
 
Back
Top