Jump to content
Sign in to follow this  
Perseus

[UI] Loot Filter

Recommended Posts

Hello,

 

I built this for for a server but I think it would be useful for the rest of the community too.

 

This feature basically allows players to hide certain dropped items on the ground. They can use this to specifically filter out garbage/low tier drops, and only see rare drops and pick them up. While 'hidden', the items will also not get picked up by Ctrl + A, so they can freely pick up all items that they are interested in without filling their inventory with garbage.

 

I made this feature available through the drop list of a monster on the CO client. You can choose to expose it however you wish. I'll add the CO-client specific changes at the end so you can use it for that if you wish.

 

I've attached a gif of what the feature looks like.

 

Code -

 

GlobalVar.cpp

At the top, add -

#include "LootFilter.h"

a bit further down -

CGameApp*	        g_pGameApp	              = NULL;
LootFilter* g_lootFilter = NULL;

 

Create the following two files in the src directory

LootFilter.h

#include "stdafx.h"
#include <map>

class LootFilter {
  public:
    LootFilter();
    ~LootFilter();

    map<int, bool> GetFilteredItems() { return lootFilter; }
    void AddFilteredItem(unsigned long itemId);
    void RemoveFilteredItem(unsigned long itemId);
    bool HasFilteredItem(unsigned long itemId);
    void PrintAllItems();
  private:
    map<int, bool> lootFilter;
};


extern LootFilter* g_lootFilter; 

LootFilter.cpp

#include "stdafx.h"
#include <map>
#include "LootFilter.h"
#include "GameApp.h"
#include <string>
#include "log.h"

LootFilter::LootFilter() {
  if (!CreateDirectory("user", NULL)) {
    DWORD dw = GetLastError();
    if ( dw != 183 ) {
      return;
    }
  }

  ifstream lootFilterFile;
  lootFilterFile.open("user\\lootfilter.txt");

  string itemIdReader;
  if (lootFilterFile.is_open()) {
    while (getline(lootFilterFile, itemIdReader)) {
      if ( itemIdReader.length() == 0) {
        continue;
      }
      int itemId = atoi(itemIdReader.c_str());
      lootFilter.insert(pair<int, bool>(itemId, TRUE));
    }
  }
}

void LootFilter::AddFilteredItem(unsigned long itemId) {
  lootFilter.insert(pair<int, bool>(itemId, TRUE));

  ofstream lootFilterFile;
  char itemIdBuffer[10];
  itoa(itemId, itemIdBuffer, 10);
  lootFilterFile.open("user\\lootfilter.txt", ios_base::app);
  lootFilterFile << string(itemIdBuffer) << std::endl;
  lootFilterFile.close();
}

void LootFilter::RemoveFilteredItem(unsigned long itemId) {
  lootFilter.erase(itemId);
  string line;
  ifstream in;
  in.open("user\\lootfilter.txt");
  ofstream temp;
  temp.open("user\\lootfilter_new.txt");

  while (getline(in, line)) {
    char itemIdBuffer[10];
    itoa(itemId, itemIdBuffer, 10);
    if (line.compare(string(itemIdBuffer)) != 0) {
      temp << line << std::endl;
    }
  }

  in.close();
  temp.close();

  remove("user\\lootfilter.txt");
  rename("user\\lootfilter_new.txt", "user\\lootfilter.txt");
}

bool LootFilter::HasFilteredItem(unsigned long itemId) {
  if ( lootFilter.find(itemId) == lootFilter.end() ) {
    return false;
  }

  return true;
}

void LootFilter::PrintAllItems() {
  map<int,bool>::iterator it = lootFilter.begin();
	for(it = lootFilter.begin(); it != lootFilter.end(); it++) {
		g_pGameApp->SysInfo("Filtered item %d %d", it->first, it->second);
	}
} 

 

In Main.cpp

At the top -

#include "LootFilter.h"

A bit further down, look for g_pGameApp -

g_pGameApp = new CGameApp();
g_lootFilter = new LootFilter();

 

Scene.h

Add this function declaration below the other ones for CSceneItem (after line 217 in CO)
 

CSceneItem* FilterItemsByItemID(unsigned long id, bool shouldHide);

Scene.cpp

Add this function somewhere in the file -

CSceneItem* CGameScene::FilterItemsByItemID(unsigned long id, bool shouldHide) {
	CSceneItem* pItem;

	for(int i = 0; i < _nSceneItemCnt; i++) {
		pItem = &_pSceneItemArray[i];

		if (pItem->IsValid()) {
			CItemRecord* itemData = pItem->GetItemInfo();
			if ( itemData ) {
				if (itemData->lID == id ) {
					pItem->SetHide(shouldHide);
				}
			}
		}
	}

	if ( !shouldHide ) {
		g_lootFilter->RemoveFilteredItem(id);
	} else {
		g_lootFilter->AddFilteredItem(id);
	}

	return NULL;
}

 

SceneItem.cpp

Replace the CSceneItem::Render function with this -

void CSceneItem::Render()
{
    if( GetScene()->GetTerrain() )
    {
	    if(!GetScene()->GetTerrain()->IsPointVisible((float)_nCurX / 100.0f, (float)_nCurY / 100.0f)) 
            return;
    }

    if ( _pItemInfo && g_lootFilter->HasFilteredItem(_pItemInfo->lID) ) {
        SetHide(TRUE);
        setIsShowName(false);
        return;
    }

	CSceneNode::Render();

	// g_Render.EnableMipmap(FALSE);
	
	MPSceneItem::Render();
}

In the CSceneItem::setIsShowName function, add this line at the top

_IsShowName = v;

 

Make sure to include the LootFilter.h and LootFilter.cpp files in your kop.vcxproj or kop.vcproj files

I had .vcxproj, so -

 

kop.vcxproj

Look for

<ClInclude Include="..\src\GameWG.h" />

and add

<ClInclude Include="..\src\LootFilter.h" />

after it.

 

kop.vcxproj.filters

Look for

<ClCompile Include="..\src\SoundCommon.cpp" />

and add

<ClCompile Include="..\src\LootFilter.cpp" />

after it.


Look for

<ClInclude Include="..\src\SoundManager.h" />

and add

<ClInclude Include="..\src\LootFilter.h" />

after it.

 

This should let you compile the given code.

 

For people who are NOT using CO files, if you want to trigger the filter for a particular item, you need to have the item ID, and then do something like this -

CGameApp::GetCurScene()->FilterItemsByItemID(itemId, true);

 

If you are using the CO client and have the monster drop UI available, I'll post how to make changes to that UI in a follow-up post below

 

 

Loot_Filter.gif

 

 

I offer NO support for any issues you may have past basic compilation. It's up to you to figure out how to integrate this if you want it.

  • Like 3
  • Thanks 1

Share this post


Link to post
Share on other sites
В 23.09.2021 в 16:30, Perseus сказал:

 

Loot_Filter.gif

 

 

I offer NO support for any issues you may have past basic compilation. It's up to you to figure out how to integrate this if you want it.

 

Hello, is this topic still relevant?

  • Confused 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...