Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // PassTheFlag.cpp : bzfs plugin to enable passing of flags (actually you throw them)
- //
- // $Id: PassTheFlag.cpp based on HTF plugin code by bullet_catcher $
- #include "bzfsAPI.h"
- #include "../../src/bzfs/bzfs.h"
- #include "../plugin_utils/plugin_utils.h"
- #include "BZDBCache.h"
- #include "../../src/bzfs/DropGeometry.h"
- #include <stdio.h>
- #include <stdarg.h>
- BZ_GET_PLUGIN_VERSION
- #define PASSTHEFLAG_VER "1.00.00"
- #define DbgLevelAlways 1
- #define DbgLevelErr 1
- #define DbgLevelWarn 2
- #define DbgLevelInfo 3
- #define DbgLevelExtraInfo 4
- //#define DbgLevelDbgInfo 5
- #define DbgLevelDbgInfo 1
- class FPassHandler : public bz_EventHandler, public bz_CustomSlashCommandHandler
- {
- public:
- virtual void process ( bz_EventData *eventData );
- virtual bool handle ( int playerID, bzApiString, bzApiString, bzAPIStringList*);
- protected:
- private:
- };
- FPassHandler FlagPassHandler;
- class PlayerStats {
- public:
- int thisPlayerID;
- float velocity[3];
- bzApiString callsign;
- void SetStats(int playerID, const float *velocity) {
- if (velocity && (this->thisPlayerID == playerID))
- {
- memcpy(this->velocity, velocity, sizeof(float[3]));
- }
- }
- void SetData(int playerID, const float *velocity, const bzApiString *callsign) {
- this->thisPlayerID = playerID;
- this->velocity[0] = velocity?velocity[0]:0.0;
- this->velocity[1] = velocity?velocity[1]:0.0;
- this->velocity[2] = velocity?velocity[2]:0.0;
- this->callsign = callsign?*callsign:bzApiString();
- }
- PlayerStats(int playerID, const float *velocity, const bzApiString *callsign) { SetData(playerID, velocity, callsign); };
- PlayerStats(const PlayerStats& inData) {
- if (this != &inData)
- {
- SetData(inData.thisPlayerID, inData.velocity, &inData.callsign);
- }
- };
- PlayerStats() { SetData(-1, NULL, NULL); };
- PlayerStats& operator=(const PlayerStats& other);
- bool operator==(const PlayerStats& other) const;
- bool operator!=(const PlayerStats& other) const { return !(*this == other); }
- };
- // operator ==
- inline bool PlayerStats::operator==(const PlayerStats& inData) const
- {
- return (thisPlayerID == inData.thisPlayerID);
- }
- PlayerStats& PlayerStats::operator=(const PlayerStats& other)
- {
- if (this != &other)
- {
- SetData(other.thisPlayerID, other.velocity, &other.callsign);
- }
- return *this;
- }
- bool FPassEnabled = true;
- bool FumbleMsg = true;
- float FPassThrowDistance = 6.0;
- int MaxSafeZoneTests = 5;
- std::vector <PlayerStats> gActivePlayers;
- PlayerStats *GetActivePlayerStatsByID(int PlayerID)
- {
- static PlayerStats UnKnown;
- UnKnown.SetData(-1, NULL, NULL);
- for(unsigned int i=0;i<gActivePlayers.size();i++)
- {
- if (gActivePlayers[i].thisPlayerID == PlayerID)
- {
- return &gActivePlayers[i];
- }
- }
- return &UnKnown;
- }
- bool RemovePlayerStatsForPlayerID(int PlayerID)
- {
- std::vector<PlayerStats>::iterator iter = gActivePlayers.begin();
- while( iter != gActivePlayers.end() )
- {
- if (iter->thisPlayerID == PlayerID)
- {
- iter = gActivePlayers.erase( iter );
- return true;
- }
- else
- ++iter;
- }
- return false;
- }
- void sendHelp (int who)
- {
- bz_sendTextMessage(BZ_SERVER, who, "FPass commands: [off|on|stat|dist=<real num 0.0 or greater>|steps=<integer 0 or greater>]");
- }
- bool do_checkFlagDropAtPoint ( int flagID, float dropPos[3], float landing[3] )
- {
- assert(world != NULL);
- const float size = BZDBCache::worldSize * 0.5f;
- float pos[3];
- pos[0] = ((dropPos[0] < -size) || (dropPos[0] > size)) ? 0.0f : dropPos[0];
- pos[1] = ((dropPos[1] < -size) || (dropPos[1] > size)) ? 0.0f : dropPos[1];
- // pos[2] = (dropPos[2] > maxWorldHeight) ? maxWorldHeight : dropPos[2];
- pos[2] = dropPos[2];
- FlagInfo& thisFlag = *FlagInfo::get(flagID);
- int flagTeam = thisFlag.flag.type->flagTeam;
- const float waterLevel = world->getWaterLevel();
- float minZ = 0.0f;
- if (waterLevel > minZ) {
- minZ = waterLevel;
- }
- const float maxZ = MAXFLOAT;
- landing[0] = pos[0];
- landing[1] = pos[1];
- landing[2] = pos[2];
- bool safelyDropped = DropGeometry::dropTeamFlag(landing, minZ, maxZ, flagTeam); // Pretend we are dropping the team flag
- return safelyDropped;
- //return world->getFlagDropPoint(FlagInfo::get(flagID), drop_pos, land_pos);
- }
- /************************** (SUB)COMMAND Implementations ... **************************/
- void FPassStats (int who)
- {
- bz_sendTextMessagef(BZ_SERVER, who, "FPass plugin version %s", PASSTHEFLAG_VER);
- bz_sendTextMessagef(BZ_SERVER, who, " Flag Passing is turned %s" , FPassEnabled ? "ON":"OFF");
- bz_sendTextMessagef(BZ_SERVER, who, " Flag Throw Distance: %f" , FPassThrowDistance);
- bz_sendTextMessagef(BZ_SERVER, who, " Max Attempts to land flag: %d" , MaxSafeZoneTests);
- bz_sendTextMessagef(BZ_SERVER, who, " Fumble Messages are turned %s" , FumbleMsg ? "ON":"OFF");
- }
- void FPassEnable (bool onoff, int who)
- {
- char msg[255];
- char ObserverMsg[] = "an observer";
- const char *PlayerName = ObserverMsg;
- if (onoff == FPassEnabled){
- bz_sendTextMessage(BZ_SERVER, who, "Flag Passing is already that way.");
- return;
- }
- FPassEnabled = onoff;
- PlayerStats *StatsForThisPlayer = GetActivePlayerStatsByID(who);
- if (StatsForThisPlayer->thisPlayerID == who)
- PlayerName = StatsForThisPlayer->callsign.c_str();
- sprintf (msg, "*** Flag Passing turned %s by %s", onoff?"ON":"OFF", PlayerName);
- bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, msg);
- }
- void FumbleMsgEnable (bool onoff, int who)
- {
- char msg[255];
- char ObserverMsg[] = "an observer";
- const char *PlayerName = ObserverMsg;
- if (onoff == FumbleMsg){
- bz_sendTextMessage(BZ_SERVER, who, "Fumble Messaging is already that way.");
- return;
- }
- FumbleMsg = onoff;
- PlayerStats *StatsForThisPlayer = GetActivePlayerStatsByID(who);
- if (StatsForThisPlayer->thisPlayerID == who)
- PlayerName = StatsForThisPlayer->callsign.c_str();
- sprintf (msg, "*** Fumble Messages turned %s by %s", onoff?"ON":"OFF", PlayerName);
- bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, msg);
- }
- bool getPlayerVelocity(int playerID, float vel[3])
- {
- PlayerStats *StatsForThisPlayer = GetActivePlayerStatsByID(playerID);
- memcpy(vel, StatsForThisPlayer->velocity, sizeof(float[3]));
- return (StatsForThisPlayer->thisPlayerID == playerID);
- }
- bool getPlayerPosition(int playerID, float PlayerPos[3])
- {
- bz_PlayerRecord* player = bz_getPlayerByIndex(playerID);
- if (!player) {
- return false;
- }
- memcpy(PlayerPos, player->pos, sizeof(float[3]));
- return true;
- }
- bool playerIsAdmin(int playerID)
- {
- bz_PlayerRecord* player = bz_getPlayerByIndex(playerID);
- if (!player) {
- return false;
- }
- return player->admin;
- }
- // handle events
- void FPassHandler::process ( bz_EventData *eventData )
- {
- // Flag Dropped
- if (bz_eFlagDroppedEvent == eventData->eventType)
- {
- if (FPassEnabled)
- {
- float PlayerVelocity[3];
- float PlayerPos[3];
- float FlagDropPos[3];
- float FlagLandingPos[3];
- bz_FlagDroppedEventData *dropData = (bz_FlagDroppedEventData*)eventData;
- bz_debugMessagef(DbgLevelDbgInfo, "++++++ FPassHandler: Player %s will drop Flag (ID:%d, Flag:%d, drop_pos:(%f, %f, %f))", GetActivePlayerStatsByID(dropData->playerID)->callsign.c_str(), dropData->playerID, dropData->flagID, dropData->pos[0], dropData->pos[1], dropData->pos[2]); fflush (stdout);
- if (getPlayerVelocity(dropData->playerID, PlayerVelocity))
- {
- bz_debugMessagef(DbgLevelDbgInfo, " velocity: %f, %f, %f", PlayerVelocity[0], PlayerVelocity[1], PlayerVelocity[2]); fflush (stdout);
- }
- else
- {
- bz_debugMessagef(DbgLevelErr, "++++++ FPassHandler: velocity: ERR"); fflush (stdout);
- return;
- }
- if ((0.0 == PlayerVelocity[0]) && (0.0 == PlayerVelocity[1]))
- return; // Nothing to do here
- if (getPlayerPosition(dropData->playerID, PlayerPos))
- {
- bz_debugMessagef(DbgLevelDbgInfo, " PlayerPos: %f, %f, %f", PlayerPos[0], PlayerPos[1], PlayerPos[2]); fflush (stdout);
- }
- else
- {
- bz_debugMessagef(DbgLevelErr, "++++++ FPassHandler: PlayerPos: ERR"); fflush (stdout);
- return;
- }
- float JumpBoost = 1.0;
- if (PlayerVelocity[2]>0.0)
- JumpBoost = 2.0;
- else
- if (PlayerVelocity[2]<0.0)
- JumpBoost = 0.5;
- FlagDropPos[0] = PlayerPos[0] + FPassThrowDistance * PlayerVelocity[0] * JumpBoost;
- FlagDropPos[1] = PlayerPos[1] + FPassThrowDistance * PlayerVelocity[1] * JumpBoost;
- FlagDropPos[2] = dropData->pos[2];
- bool PassWasFumbled = false;
- bool ValidFlagThrow;
- int TriesLeft = MaxSafeZoneTests;
- float DeltaX, DeltaY ;
- DeltaX = DeltaY = 0.0;
- if (0 < MaxSafeZoneTests)
- {
- DeltaX = (PlayerPos[0] - FlagDropPos[0])/MaxSafeZoneTests;
- DeltaY = (PlayerPos[1] - FlagDropPos[1])/MaxSafeZoneTests;
- }
- do
- {
- ValidFlagThrow = do_checkFlagDropAtPoint(dropData->flagID, FlagDropPos, FlagLandingPos);
- // Check for flags that were left up high
- if (ValidFlagThrow)
- ValidFlagThrow = FlagLandingPos[2] <= FlagDropPos[2];
- // Check for flags that need to be moved
- if (ValidFlagThrow)
- ValidFlagThrow = (FlagLandingPos[0] == FlagDropPos[0]) && (FlagLandingPos[1] == FlagDropPos[1]); // Perhaps we should allow a tolerance here
- if (!PassWasFumbled)
- PassWasFumbled = !ValidFlagThrow;
- TriesLeft--;
- if ((!ValidFlagThrow) && (TriesLeft >= 0))
- {
- FlagDropPos[0] += DeltaX;
- FlagDropPos[1] += DeltaY;
- }
- }
- while ((!ValidFlagThrow) && (TriesLeft >= 0));
- if (PassWasFumbled && FumbleMsg)
- {
- bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "%s fumbled the pass.", GetActivePlayerStatsByID(dropData->playerID)->callsign.c_str());
- }
- if (!ValidFlagThrow)
- {
- bz_debugMessagef(DbgLevelDbgInfo, " PlayerPos: Invalid Drop Point!! DropPos=(%f, %f, %f) FlagLandingPos: %f, %f, %f", FlagDropPos[0], FlagDropPos[1], FlagDropPos[2], FlagLandingPos[0], FlagLandingPos[1], FlagLandingPos[2]); fflush (stdout);
- }
- else
- {
- FlagInfo& flag = *FlagInfo::get(dropData->flagID);
- flag.dropFlag(dropData->pos, FlagLandingPos, false);
- sendDrop(flag);
- sendFlagUpdate(flag);
- bz_debugMessagef(DbgLevelDbgInfo, " FlagLandingPos: %f, %f, %f", FlagLandingPos[0], FlagLandingPos[1], FlagLandingPos[2]); fflush (stdout);
- }
- }
- }
- else if (bz_ePlayerUpdateEvent == eventData->eventType)
- {
- bz_PlayerUpdateEventData* playerupdatedata = (bz_PlayerUpdateEventData*)eventData;
- //bz_debugMessagef(DbgLevelDbgInfo, "++++++ FPassHandler: PlayerUpdateEvent for player %d velocity = %f, %f, %f", playerupdatedata->playerID, playerupdatedata->velocity[0], playerupdatedata->velocity[1], playerupdatedata->velocity[2]); fflush (stdout);
- PlayerStats *StatsForThisPlayer = GetActivePlayerStatsByID(playerupdatedata->playerID);
- if (StatsForThisPlayer->thisPlayerID == playerupdatedata->playerID)
- {
- StatsForThisPlayer->SetStats(playerupdatedata->playerID, playerupdatedata->velocity);
- //bz_debugMessagef(DbgLevelDbgInfo, "++++++ FPassHandler: PlayerUpdateEvent for player %d", playerupdatedata->playerID); fflush (stdout);
- }
- else
- {
- bz_debugMessagef(DbgLevelErr, "++++++ FPassHandler: PlayerUpdate: ERR"); fflush (stdout);
- }
- }
- else if (bz_ePlayerJoinEvent == eventData->eventType)
- {
- bz_PlayerJoinPartEventData *joinData = (bz_PlayerJoinPartEventData*)eventData;
- if (joinData->team != eObservers)
- {
- float NoVelocity[3];
- NoVelocity[0] = NoVelocity[1] = NoVelocity[2] = 0.0;
- PlayerStats NewPlayer(joinData->playerID, NoVelocity, &joinData->callsign);
- gActivePlayers.push_back(NewPlayer);
- bz_debugMessagef(DbgLevelDbgInfo, "++++++ FPassHandler: created PlayerStats for %d", joinData->playerID); fflush (stdout);
- }
- }
- else if (bz_ePlayerPartEvent == eventData->eventType)
- {
- bz_PlayerJoinPartEventData *partingData = (bz_PlayerJoinPartEventData*)eventData;
- if (partingData->team != eObservers)
- {
- if (RemovePlayerStatsForPlayerID(partingData->playerID))
- {
- bz_debugMessagef(DbgLevelDbgInfo, "++++++ FPassHandler: removed PlayerStats for %d", partingData->playerID); fflush (stdout);
- }
- else
- {
- bz_debugMessagef(DbgLevelErr, "++++++ FPassHandler: ERR no PlayerStats for player %d", partingData->playerID); fflush (stdout);
- }
- }
- }
- }
- bool checkPerms (int playerID, const char *FPassCmd, const char *permName)
- {
- bool HasPerm = false;
- return true;//zxcv
- if ('\0' == *permName) // Needs Admin
- HasPerm = playerIsAdmin (playerID);
- else
- HasPerm = bz_hasPerm (playerID, permName);
- if (!HasPerm)
- bz_sendTextMessagef (BZ_SERVER, BZ_ALLUSERS, "you need \"%s\" permission to do /FPass %s", *permName?permName:"Admin", FPassCmd);
- return HasPerm;
- }
- bool SetThrowDistance(const char *FloatStr, int *CharsUsed)
- {
- float FloatVal = 0.0;
- char *EndOfNum = (char *) FloatStr;
- FloatVal = strtof (FloatStr, &EndOfNum);
- if (EndOfNum == FloatStr)
- return false;
- if (CharsUsed)
- *CharsUsed = (EndOfNum - FloatStr);
- bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "++++++ FPassHandler: Flag Throw Distance: Chaged from %f to %f", FPassThrowDistance, FloatVal); fflush (stdout);
- FPassThrowDistance = FloatVal;
- return true;
- }
- bool SetMaxIterations(const char *IntStr)
- {
- int IntVal = 0;
- char *EndOfNum = (char *) IntStr;
- IntVal = strtol (IntStr, &EndOfNum, 10);
- if (EndOfNum == IntStr)
- return false;
- bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, "++++++ FPassHandler: Max Attempts to land flag: Chaged from %d to %d", MaxSafeZoneTests, IntVal);
- MaxSafeZoneTests = IntVal;
- return true;
- }
- // handle /FPass command
- bool FPassHandler::handle ( int playerID, bzApiString cmd, bzApiString, bzAPIStringList* cmdParams )
- {
- char subCmd[8];
- if (strcasecmp (cmd.c_str(), "fpass")) // is it for me ?
- return false;
- if (cmdParams->get(0).c_str()[0] == '\0'){
- FPassStats (playerID);
- return true;
- }
- bz_debugMessagef(DbgLevelDbgInfo, "++++++ FPassHandler::handle: cmdParams->get(0).c_str() = \"%s\"", cmdParams->get(0).c_str()); fflush (stdout);
- strncpy (subCmd, cmdParams->get(0).c_str(), 7);
- subCmd[6] = '\0';
- bz_debugMessagef(DbgLevelDbgInfo, "++++++ FPassHandler::handle: subCmd = \"%s\"", subCmd); fflush (stdout);
- if (strncasecmp (subCmd, "dist=", 5) == 0){
- if (checkPerms (playerID, "dist", ""))
- {
- if (!SetThrowDistance(cmdParams->get(0).c_str() + 5, NULL))
- {
- sendHelp(playerID);
- }
- }
- } else if (strncasecmp (subCmd, "fmsg=", 5) == 0){
- if (checkPerms (playerID, "fmsg", ""))
- {
- char CmdParam[5];
- strncpy (CmdParam, cmdParams->get(0).c_str() + 5, 4);
- if (strcasecmp (CmdParam, "off") == 0)
- FumbleMsgEnable (false, playerID);
- else if (strcasecmp (CmdParam, "on") == 0)
- FumbleMsgEnable (true, playerID);
- else
- {
- sendHelp(playerID);
- }
- }
- } else if (strcasecmp (subCmd, "steps=") == 0){
- if (checkPerms (playerID, "steps", ""))
- {
- if (!SetMaxIterations(cmdParams->get(0).c_str() + 6))
- {
- sendHelp(playerID);
- }
- }
- } else if (strcasecmp (subCmd, "off") == 0){
- if (checkPerms (playerID, "off", "COUNTDOWN"))
- FPassEnable (false, playerID);
- } else if (strcasecmp (subCmd, "on") == 0){
- if (checkPerms (playerID, "on", "COUNTDOWN"))
- FPassEnable (true, playerID);
- } else if (strcasecmp (subCmd, "stat") == 0)
- FPassStats (playerID);
- else
- sendHelp (playerID);
- return true;
- }
- bool commandLineHelp (void){
- const char *help[] = {
- "Command line args: PLUGINNAME[,dist=<0.0 .. 10.0>][,steps=<0 .. 20>],",
- NULL
- };
- bz_debugMessage (0, "+++ PassTheFlag plugin command-line error");
- for (int x=0; help[x]!=NULL; x++)
- bz_debugMessage (0, help[x]);
- return true;
- }
- bool parseCommandLine (const char *cmdLine)
- {
- int CharOffset = 0;
- if (cmdLine==NULL || *cmdLine=='\0')
- return false;
- if (strncasecmp (cmdLine, "dist=", 5) == 0)
- {
- if (!SetThrowDistance(cmdLine+5, &CharOffset))
- return commandLineHelp ();
- else
- CharOffset += 5 + 1;
- }
- if (strncasecmp (cmdLine + CharOffset, "steps=", 6) == 0)
- {
- if (!SetMaxIterations(cmdLine+6+CharOffset))
- return commandLineHelp ();
- }
- return false;
- }
- BZF_PLUGIN_CALL int bz_Load (const char* cmdLine)
- {
- if (parseCommandLine (cmdLine))
- return -1;
- bz_registerCustomSlashCommand ("fpass", &FlagPassHandler);
- bz_registerEvent(bz_eFlagDroppedEvent, &FlagPassHandler);
- bz_registerEvent(bz_ePlayerJoinEvent, &FlagPassHandler);
- bz_registerEvent(bz_ePlayerPartEvent, &FlagPassHandler);
- bz_registerEvent(bz_ePlayerUpdateEvent, &FlagPassHandler);
- bz_debugMessagef(DbgLevelAlways, "PassTheFlag plugin loaded - v%s ApiVersion=v%d", PASSTHEFLAG_VER, BZ_API_VERSION);
- return 0;
- }
- BZF_PLUGIN_CALL int bz_Unload (void)
- {
- bz_removeCustomSlashCommand ("fpass");
- bz_removeEvent (bz_eFlagDroppedEvent, &FlagPassHandler);
- bz_removeEvent (bz_ePlayerJoinEvent, &FlagPassHandler);
- bz_removeEvent (bz_ePlayerPartEvent, &FlagPassHandler);
- bz_removeEvent (bz_ePlayerUpdateEvent, &FlagPassHandler);
- bz_debugMessage(DbgLevelAlways, "PassTheFlag plugin unloaded");
- return 0;
- }
- // Local Variables: ***
- // mode:C++ ***
- // tab-width: 8 ***
- // c-basic-offset: 2 ***
- // indent-tabs-mode: t ***
- // End: ***
- // ex: shiftwidth=2 tabstop=8
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement