All pastes #71820 Raw Edit

Miscellany

public text v1 · immutable
#71820 ·published 2006-06-26 05:30 UTC
rendered paste body
 // compound.cpp : Defines the entry point for the DLL application.
//

#include <cstdlib>
#include <map>
#include <vector>

#include "bzfsAPI.h"

BZ_GET_PLUGIN_VERSION

class Compound : public bz_EventHandler
{
public:
	virtual void process(bz_EventData *eventData);
	void setclass(int playerid, int newclass);
	int chooseclass(bz_eTeamType team);

	std::map<int,int> playerclasses;

	int teamclasscounts[5][6];
	
	std::vector<std::string> flags[6];

};

Compound compound;

BZF_PLUGIN_CALL int bz_Load ( const char* /*commandLine*/ )
{
	for (int x = 0; x < 5; x++)
	{
		for (int y = 0; y < 6; y++)
		{
			compound.teamclasscounts[x][y] = 0;
		}
	}

	compound.flags[1].push_back(std::string("ST"));
	compound.flags[1].push_back(std::string("WG"));
	compound.flags[1].push_back(std::string("OO"));

	compound.flags[2].push_back(std::string("SW"));
	compound.flags[2].push_back(std::string("SB"));
	compound.flags[2].push_back(std::string("BU"));

	compound.flags[3].push_back(std::string("L"));
	compound.flags[3].push_back(std::string("GM"));
	compound.flags[3].push_back(std::string("G"));
	compound.flags[3].push_back(std::string("F"));
	compound.flags[3].push_back(std::string("MG"));

	compound.flags[4].push_back(std::string("CL"));
	compound.flags[4].push_back(std::string("SH"));
	compound.flags[4].push_back(std::string("T"));
	compound.flags[4].push_back(std::string("N"));

	compound.flags[5].push_back(std::string("QT"));
	compound.flags[5].push_back(std::string("V"));
	compound.flags[5].push_back(std::string("A"));
	compound.flags[5].push_back(std::string("SR"));

  bz_registerEvent(bz_ePlayerJoinEvent, &compound);
  bz_registerEvent(bz_ePlayerSpawnEvent, &compound);
  bz_registerEvent(bz_ePlayerDieEvent, &compound);
  bz_registerEvent(bz_eCaptureEvent, &compound);
  bz_debugMessage(4,"compound plugin loaded");
  return 0;
}

BZF_PLUGIN_CALL int bz_Unload ( void )
{
  bz_removeEvent(bz_ePlayerJoinEvent, &compound);
  bz_removeEvent(bz_ePlayerSpawnEvent, &compound);
  bz_removeEvent(bz_ePlayerDieEvent, &compound);
  bz_removeEvent(bz_eCaptureEvent, &compound);
  bz_debugMessage(4,"compound plugin unloaded");
  return 0;
}

void Compound::process(bz_EventData *eventData)
{
	if (eventData->eventType == bz_ePlayerJoinEvent)
	{
		bz_PlayerJoinPartEventData* joindata = (bz_PlayerJoinPartEventData*)eventData;

		playerclasses[joindata->playerID] = 0;
		teamclasscounts[joindata->team][0]++;
	}

	else if (eventData->eventType == bz_ePlayerSpawnEvent)
	{
		bz_PlayerSpawnEventData *spawndata = (bz_PlayerSpawnEventData*)eventData;
	
		bz_PlayerRecord *pi = bz_getPlayerByIndex (spawndata->playerID);
		if (pi == NULL)
		{
			return; //bogus player, WTF case
		}

		//pick and set a class
		int newclass = chooseclass(pi->team); 

		setclass(spawndata->playerID, newclass);

		//pick a flag
		for (int a = 0; a < 10; a++)
		{
			int flagnum = std::rand() % flags[newclass].size();
			std::string flag = flags[newclass].at(flagnum);
		
			if (bz_givePlayerFlag(spawndata->playerID, flag.c_str(), false))
			{
				break;
			}
		}
		

		bz_freePlayerRecord(pi);
	}

	else if (eventData->eventType == bz_ePlayerDieEvent)
	{
		bz_PlayerDieEventData *diedata = (bz_PlayerDieEventData*)eventData;

		setclass(diedata->playerID,0);

	}

	else if (eventData->eventType == bz_eCaptureEvent)
	{
		bz_CTFCaptureEventData *ctfdata = (bz_CTFCaptureEventData*)eventData;

		bzAPIIntList* pl = bz_newIntList();
		bz_getPlayerIndexList (pl);

		//kill anyone who's in the losing team's base
		for (int x = 0; x < pl->size(); x++)
		{
			bz_PlayerRecord *pi = bz_getPlayerByIndex (pl->get(x));
			if (pi != NULL)
			{
				if (pi->team != ctfdata->teamCapped)
				{
					if (
						(ctfdata->teamCapped == eRedTeam && pi->pos[0] <= -200.0 && pi->pos[1] <= -200.0) ||
						(ctfdata->teamCapped == eGreenTeam && pi->pos[0] >= 200.0 && pi->pos[1] <= -200.0) ||
						(ctfdata->teamCapped == eBlueTeam && pi->pos[0] <= -200.0 && pi->pos[1] >= 200.0) ||
						(ctfdata->teamCapped == ePurpleTeam && pi->pos[0] >= 200.0 && pi->pos[1] >= 200.0)
					)
					{
						bz_fireWorldWep("SW", 1.0, BZ_SERVER, pi->pos, 0.0, 0.0, 0, 0.0);
						bz_fireWorldWep("SW", 1.0, BZ_SERVER, pi->pos, 0.0, 0.0, 0, 0.0); //booooom

					}
				}

				bz_freePlayerRecord (pi);
			}
		}
		bz_deleteIntList(pl);
	}
}

void Compound::setclass(int playerid, int newclass)
{
	bz_PlayerRecord *pi = bz_getPlayerByIndex (playerid);
	if (pi == NULL)
	{
		return; //bogus player
	}

	teamclasscounts[pi->team][playerclasses[playerid]]--;
	teamclasscounts[pi->team][newclass]++;

	playerclasses[playerid] = newclass;

	bz_freePlayerRecord(pi);

}

int Compound::chooseclass(bz_eTeamType team)
{
	if (team < 0 || team > 4)
	{
		return 0;
	}

	int min = 1000000; //something ridiculous

	for (int x = 1; x < 6; x++)
	{
		if (teamclasscounts[team][x] < min)
		{
			min = teamclasscounts[team][x];
		}
	}

	std::vector<int> choices;

	for (int y = 1; y < 6; y++)
	{
		if (teamclasscounts[team][y] == min)
		{
			choices.push_back(y);
		}
	}

	if (choices.size() == 0)
	{
		return 0; //"WTF" case
	}
	if (choices.size() == 1)
	{
		return choices.at(0);
	}
	else
	{
		int choice = std::rand() % choices.size();

		return choices.at(choice);
		
	}
}
	

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8