UselessMine - Create Mines with the Useless Flag Once Again!

Expand and mod your server.
Post Reply
User avatar
SkillDude
Private First Class
Private First Class
Posts: 336
Joined: Sun Apr 01, 2007 4:50 pm
Location: United States

UselessMine - Create Mines with the Useless Flag Once Again!

Post by SkillDude » Thu Sep 15, 2011 10:37 am

Plugin Name: Useless Mine
Minimum Version: 2.4.0
License: Public Domain
Author: sigonasr2 (Joshua Sigona)

This plugin is the Useless Mine plugin. It has once been created beforehand by Enigma, and has been re-implemented for version 2.4.0 along with a few tweaks.

The original shot types from the 2.0 version of Useless Mine have been removed. The cr, sr, and sb options were all neat, but were not nearly as useful or guaranteed as a shockwave, so they have been removed. Because there is only one type of mine now, the command has been stripped down to just /mine. This should make it easier for players to type and realize what to do.

Just like Enigma's plugin, it is completely possible to avoid the mine if you creep up to it very slowly. So there can be some tactic to disarming them. :)

Plugin considers the _shockOutRadius variable, so changing that will automatically increase or decrease the range of the mine accordingly!

Speaking of making it easier for players, whenever they do grab a useless flag, they are notified with the message "You have grabbed a useless flag! Type /mine to set a mine!". Very helpful for them and provides them with information about the mine plugin without needed a help file.

In addition, this plugin also has some witty comments when players get destroyed by mines. The number of mines still set, just like the previous version is also displayed in [] brackets at the end of the server message.

Enjoy! Plugin is in the Public Domain.
Attachments
uselessmine.cpp
Useless Mine Source File - 2.4.0
(9.56 KiB) Downloaded 245 times
Last edited by SkillDude on Sat Oct 08, 2011 9:06 pm, edited 1 time in total.

User avatar
allejo
Breaker of Builds
Breaker of Builds
Posts: 726
Joined: Sun Feb 17, 2008 10:01 pm
Location: /dev/null
Contact:

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by allejo » Thu Sep 22, 2011 9:27 pm

Nothing against Enigma's genius-ness, but this is a much a simpler version. love it :D
Here's my personal website and my open source projects are available on GitHub; I work on a lot of cool things.

Image

Enigma
Private First Class
Private First Class
Posts: 211
Joined: Sat Apr 23, 2005 3:13 am

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by Enigma » Sat Oct 01, 2011 11:20 pm

You know, I have thought about just using a single mine type for a while, and I actually started on a plug-in that only used shock waves. Somehow I managed to lose the code, and I didn't want to start all over again, so I gave up. I have been away from BZFlag as well.

I like that someone made changes to my code :-). And you wrote the whole thing with only 250 lines of code. I always end up with a ton more code than I need. The reason is I get stuck on smaller problems, or sub-problems of my original problem. I'll spend a lot of time thinking about better ways doing things. But anyways, I also like the random messages.

Although I probably won't write any plug-ins, I have a few comments on your code. I mean them as constructive comments.

If you use a map instead of a switch statement, your code will clean up better.

Code: Select all

// Define this in your class.
std::map<int, std::string> wittyMsgMap;

// Put this in your constructor.
wittyMsgMap[0] = '"%s was killed by %s's mine. [%d]";
wittyMsgMap[1] = "%s was owned by %s's mine. [%d]";
...
wittyMsgMap[19] = "I ascertain that %s has been ruptured by a mine created from the heavens with the name dubbed %s. [%d]";


// Then send the message.
msg = wittyMsgMap[rand() % wittyMsgMap.size()];
bz_sendTextMessagef(BZ_SERVER, BZ_ALLUSERS, msg.c_str(), pr->callsign.c_str(), kr->callsign.c_str(), CountMines());
All of the functions in your class are declared as virtual. You might want to look up virtual functions. A virtual function is a function that can be re-implemented by a subclass. There are also pure virtual functions. Pure virtual functions must be redefined by every direct subclass. Using virtual functions here is harmless, but I don't think you intend on subclassing the uselessmine class. It would be better to write:

Code: Select all

virtual const char* Name (){return "Useless Mine";}
	void Init (const char* /*config*/);
	void Event(bz_EventData *eventData);
	bool SlashCommand (int playerID,bz_ApiString command,bz_ApiString message,bz_APIStringList* params);
	void Cleanup ();
	int CountMines();
	void SetMine(int playerID,float pos1,float pos2,float pos3);
	void RemoveMine(int id);
	void RemoveAllMines(int playerID);
There is a better way you could count the mines. Instead of looping through an array every time you want to count the number of mines, you could use a state variable. When someone adds a mine, increment by one, and when someone removes a mine, decrement by one.

What wasn't working with the following code? Using the flag grabbed event would be a better way of handling flag grabbed messages. Maybe instead of getting the flag type from the player, you should get the flag type from the event data? The grabbed flag type is stored in the bz_FlagGrabbedEventData_V1 class. Using the flag grabbed event, you could remove the minenotify array.

Code: Select all

case bz_eFlagGrabbedEvent: {
			playerID=((bz_FlagGrabbedEventData_V1*)eventData)->playerID;
			/*bz_BasePlayerRecord *pr = bz_getPlayerByIndex(playerID);
			//bz_debugMessage(0,bz_getName(((bz_FlagGrabbedEventData_V1*)eventData)->flagID).c_str());
			if (pr) {
			if (!strcmp(pr->currentFlag.c_str(),"US")) {
				bz_sendTextMessage(BZ_SERVER,playerID,"You grabbed a Useless flag! Type /mine at any time to set a useless mine!");
			}
			bz_freePlayerRecord(pr);
			}*/
			minenotify[playerID]=1;
		}break;
I'm pretty sure calling delete on a null pointer does nothing, so it isn't necessary to check if a pointer actually points to something before deleting it.

Code: Select all

if (pr)
  bz_freePlayerRecord(pr);
if (kr)
  bz_freePlayerRecord(kr);
If anything, you should perform these checks when you allocate memory.

Code: Select all

bz_BasePlayerRecord *pr = bz_getPlayerByIndex(playerID);

if (!pr)
  return;

bz_BasePlayerRecord *kr = bz_getPlayerByIndex(mineplayer[i]);

if (!kr)
{
  bz_freePlayerRecord(pr);
  return;
}

// If we get to this point, then everything allocated properly.
In my original code, I actually used template metaprogramming to unroll loops at compile time when computing the vector product. I honestly shouldn't have done that because it overly complicated things when it wasn't necessary. My excuse is I was learning about template metaprogramming at the time ;-). But anyways, I guess you would prefer a bounding box rather than a sphere? I would just use the Euclidean distance http://en.wikipedia.org/wiki/Euclidean_distance.

Code: Select all

for (i=0;i<255;i++) {
					if (mine[i] && mineplayer[i]!=playerID && (pr->team==eRogueTeam || pr->team!=mineteam[i])) {
						if (pr->lastKnownState.pos[0]>minepos[i][0]-((bz_getBZDBDouble("_shockOutRadius")*0.75))
						&& pr->lastKnownState.pos[0]<minepos[i][0]+((bz_getBZDBDouble("_shockOutRadius")*0.75))
						&& pr->lastKnownState.pos[1]>minepos[i][1]-((bz_getBZDBDouble("_shockOutRadius")*0.75))
						&& pr->lastKnownState.pos[1]<minepos[i][1]+((bz_getBZDBDouble("_shockOutRadius")*0.75))
						&& pr->lastKnownState.pos[2]>minepos[i][2]-((bz_getBZDBDouble("_shockOutRadius")*0.75))
						&& pr->lastKnownState.pos[2]<minepos[i][2]+((bz_getBZDBDouble("_shockOutRadius")*0.75))
						&& safetytime[playerID]<=bz_getCurrentTime()
						) {
							bz_fireWorldWep("SW",2.0,BZ_SERVER,minepos[i],0,0,i+1000,0);
							RemoveMine(i);
						}
					}
			}
I think that is about it. My only other suggestion would be to use standard library containers instead of constant length arrays. You would need a random access container, since removing "mines" requires random access. That is, you need to be able to remove elements from the middle of the array.

Enigma
Private First Class
Private First Class
Posts: 211
Joined: Sat Apr 23, 2005 3:13 am

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by Enigma » Sat Oct 01, 2011 11:30 pm

Actually one more suggestion. For good programming, you should avoid repeating yourself. I'm referring to the DRY principle. What I mean is, you should avoid duplicate code as much as possible.

You use 255 for the size of several arrays. You should define a constant, say
MAX_MINE_COUNT = 255;
Then use this everywhere it makes sense. Later if you decide to change the size, you will only need to change one variable. Otherwise you would have to change every instance of 255. you can apply the same concept to functions and variables and probably other things.

cidentan50
Private First Class
Private First Class
Posts: 38
Joined: Thu Jan 19, 2006 8:20 pm

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by cidentan50 » Wed Nov 02, 2011 12:29 am

The problem with any of these mine plugins is that if a user lays a lot of mines, he or she will get warned and eventually kicked for spamming. That's because /mine is treated like any other chat message. I've run into that several times on maps with mine plugins. Is there a way to have the BZflag spam checker not count certain types of messages?

User avatar
SkillDude
Private First Class
Private First Class
Posts: 336
Joined: Sun Apr 01, 2007 4:50 pm
Location: United States

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by SkillDude » Wed Nov 02, 2011 1:37 am

Implement a custom spam kicker if you are inclined to needing to kick other players that do have spam messages to make sure the command in question is not included in that. Better yet, just do that for any slash command the user tries to run. However, I highly recommend just using spam warning times of 1 second. Anyone who talks with messages at least a second apart is definitely not spamming, or not spamming to the extent where hundreds of messages are appearing.

As an offset note, thank you Enigma for pointing out your programming tips and advice. It will really benefit me in the future.
Last edited by SkillDude on Wed Nov 02, 2011 8:27 pm, edited 1 time in total.

User avatar
FangUp
Private First Class
Private First Class
Posts: 96
Joined: Fri Aug 21, 2009 2:53 pm
Location: Slovenia

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by FangUp » Wed Nov 02, 2011 8:06 pm

May i ask you, is this the mine you guys are commenting about, the mine that may be set on SW or SB?
To be or not to be. - W. Shakespeare
To bee or not to bee? I sure love Honee! - FangUp
Playing since 2005, with an unregistered nickname.

cidentan50
Private First Class
Private First Class
Posts: 38
Joined: Thu Jan 19, 2006 8:20 pm

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by cidentan50 » Wed Nov 02, 2011 9:26 pm

No, this thread is about the plugin that's SW only. You type /mine and that's it. No other options.

User avatar
FangUp
Private First Class
Private First Class
Posts: 96
Joined: Fri Aug 21, 2009 2:53 pm
Location: Slovenia

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by FangUp » Wed Nov 02, 2011 9:33 pm

ok. Because i once played on a map where there were around 100 US flags. You could write in "/mine SW" or "/mine SB" (practicly same result) Good idea for the mines.
To be or not to be. - W. Shakespeare
To bee or not to bee? I sure love Honee! - FangUp
Playing since 2005, with an unregistered nickname.

Jacko H
Private First Class
Private First Class
Posts: 123
Joined: Wed Apr 22, 2009 3:15 am

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by Jacko H » Thu Mar 01, 2012 12:05 am

what is the actual thing you put in the config? -loadplugin (what in here?)
Jacko Productions:
World War III, Kill Or Die, Nazarath, Warlock Adrenaline, Rabbit Season, Firing Range (Just Be Simple), Death Island.

User avatar
blast
General
General
Posts: 4684
Joined: Fri Mar 21, 2003 3:49 pm
Location: playing.cxx
Contact:

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by blast » Thu Mar 01, 2012 12:47 am

It doesn't take any special options. Just load the plugin like you would any other.
"In addition to knowing the secrets of the Universe, I can assure you that I am also quite potty trained." -Koenma (Yu Yu Hakusho)

Image

easy tank
Private First Class
Private First Class
Posts: 37
Joined: Sat Dec 04, 2010 8:38 am

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by easy tank » Tue Apr 17, 2012 1:12 pm

I cannot load the plugin. I put -loadplugin ./uselessmine.cpp in config file and it doesn't work :/
Can anyone help me with that problem? Thanks alot!

User avatar
joevano
General
General
Posts: 1863
Joined: Sat Jun 18, 2005 1:08 pm
Location: South Bend, Indiana, USA

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by joevano » Tue Apr 17, 2012 1:38 pm

Easy Tank wrote:I cannot load the plugin. I put -loadplugin ./uselessmine.cpp in config file and it doesn't work :/
Can anyone help me with that problem? Thanks alot!
That is the source code for the plugin. You must compile it for the specific version of bzflag you are using.
There is nothing worse than aggressive stupidity. -- Johann Wolfgang von Goethe
"How many legs does a dog have if you call his tail a leg? Four. Calling a tail a leg doesn't make it a leg." -- Abraham Lincoln

Jacko H
Private First Class
Private First Class
Posts: 123
Joined: Wed Apr 22, 2009 3:15 am

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by Jacko H » Tue Apr 17, 2012 1:42 pm

sig can you please compile so we can use it.
Jacko Productions:
World War III, Kill Or Die, Nazarath, Warlock Adrenaline, Rabbit Season, Firing Range (Just Be Simple), Death Island.

User avatar
blast
General
General
Posts: 4684
Joined: Fri Mar 21, 2003 3:49 pm
Location: playing.cxx
Contact:

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by blast » Tue Apr 17, 2012 2:38 pm

Anyone serious about server hosting should be compiling the server from the latest SVN source already. Just add the plugin to your build system.
"In addition to knowing the secrets of the Universe, I can assure you that I am also quite potty trained." -Koenma (Yu Yu Hakusho)

Image

User avatar
I_Died_Once
Special Forces
Special Forces
Posts: 635
Joined: Sun Nov 28, 2004 5:27 pm
Location: The Dark Side
Contact:

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by I_Died_Once » Wed Apr 18, 2012 12:30 am

Easy Tank & Jack-O, I could have sworn I told you this last night when you were asking me on the Apocalypse... You (or whoever is hosting your server) are going to have to compile the plugin from source. In short, to do this you 'cd' into the directory where the source (and other files associated) are needed and type in 'make' - (assuming you are using a linux operating system) and optionally 'make install'

See this page for more info, this is the full run down on exactly what you are seeking. If this is out of the scope of your capabilities, you might want to reconsider taking on hosting duties.

http://wiki.bzflag.org/Plug-ins

Try listening when someone is telling you what you are seeking to find out next time.
Much love & good luck.
...This has been a recording.

User avatar
blast
General
General
Posts: 4684
Joined: Fri Mar 21, 2003 3:49 pm
Location: playing.cxx
Contact:

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by blast » Fri May 11, 2012 9:41 pm

Here is a compiled DLL for version 2.4.0 on Windows.
Attachments
uselessmine.zip
uselessmine plugin DLL built for BZFlag 2.4.0 on Windows
(7.09 KiB) Downloaded 146 times
"In addition to knowing the secrets of the Universe, I can assure you that I am also quite potty trained." -Koenma (Yu Yu Hakusho)

Image

User avatar
allejo
Breaker of Builds
Breaker of Builds
Posts: 726
Joined: Sun Feb 17, 2008 10:01 pm
Location: /dev/null
Contact:

Re: UselessMine - Create Mines with the Useless Flag Once Ag

Post by allejo » Fri Sep 05, 2014 6:24 am

And because I felt like writing my own implementation out of boredom, knock yourself out. It works the same way as sigonasr2's implementation, it's just written differently.

Like with all my plug-ins, read the README file and my source code is documented.

README
UselessMine.cpp

Update 2016-01-18: I've fixed a plug-in bug that made kill assignment inaccurate with my plug-in (commit 39cc1be).
Update 2018-03-30: The plug-in has been updated to require bzfs 2.4.14+ which improves kill assignments a lot.
Here's my personal website and my open source projects are available on GitHub; I work on a lot of cool things.

Image

User avatar
optic delusion
Special Forces
Special Forces
Posts: 967
Joined: Sat Sep 25, 2004 2:29 pm
Location: Planet MoFo
Contact:

Re: UselessMine - Create Mines with the Useless Flag Once Again!

Post by optic delusion » Sun Jun 03, 2018 2:47 pm

In the grenade plugin, we can make the size of the shockwave produced smaller than _shockOutRadius, (but not larger). This is done by ending the shock early. Also, the speed of the shock's enlargement can be controled.
Can this effect be applied to this plugin?
Take a look at my Defender game mode concept.

Thinking is not an automatic process. A man can choose to think or to let his mind stagnate, or he can choose actively to turn against his intelligence, to evade his knowledge, to subvert his reason. If he refuses to think, he courts disaster: he cannot with impunity reject his means of perceiving reality.

User avatar
allejo
Breaker of Builds
Breaker of Builds
Posts: 726
Joined: Sun Feb 17, 2008 10:01 pm
Location: /dev/null
Contact:

Re: UselessMine - Create Mines with the Useless Flag Once Again!

Post by allejo » Fri Jun 08, 2018 5:55 am

optic delusion wrote:
Sun Jun 03, 2018 2:47 pm
In the grenade plugin, we can make the size of the shockwave produced smaller than _shockOutRadius, (but not larger). This is done by ending the shock early. Also, the speed of the shock's enlargement can be controled.
Can this effect be applied to this plugin?
I believed I followed up with you about this on IRC, but to document the answer to your question: this is no longer possible. After the world weapon API was rewritten in 2.4.14, all world weapons respect and behave like a regular player shot would. This was done since BZFlag is going to start moving towards consistency for several aspects of the game.

The way the grenade plug-in works, if I remember correctly, is that it bypasses the API and handles sending shots on its own, which is why it has control of modifying SWs like that.
Here's my personal website and my open source projects are available on GitHub; I work on a lot of cool things.

Image

User avatar
Zehra
Private First Class
Private First Class
Posts: 453
Joined: Sun Oct 18, 2015 3:36 pm
Location: Arctic
Contact:

Re: UselessMine - Create Mines with the Useless Flag Once Again!

Post by Zehra » Sat Jun 09, 2018 12:04 am

To add a bit to what allejo has said, there is also a few minor notes I'll make.

The grenade plug-in did a few things which were a bit different from other plug-ins.

Code: Select all

#include "bzfsAPI.h"
#include "../src/bzfs/bzfs.h"

#include <memory>

using namespace std;
It access directly "bzfs.h", a practice which is highly and strongly discouraged.(Note this is not "bzfsAPI.h", but "bzfs.h")
It also seems to "directly" fire world weapons, instead of using the API.

Code: Select all

static int sendShot(FlagType *f, float lifetime, TeamColor t, float *p,
                    float tilt, float dir, int shotId, float speed) {
  void *buf, *bufStart = getDirectMessageBuffer();
  FiringInfo firingInfo;
  firingInfo.timeSent = (float)TimeKeeper::getCurrent().getSeconds();
  firingInfo.flagType = f;
  firingInfo.lifetime = lifetime;
  firingInfo.shot.player = ServerPlayer;
  memmove(firingInfo.shot.pos, p, 3 * sizeof(float));
  const float tiltFactor = cosf(tilt);
  firingInfo.shot.vel[0] = speed * tiltFactor * cosf(dir);
  firingInfo.shot.vel[1] = speed * tiltFactor * sinf(dir);
  firingInfo.shot.vel[2] = speed * sinf(tilt);
  firingInfo.shot.id = shotId;
  firingInfo.shot.dt = 0.0f;
  firingInfo.shot.team = t;
  buf = firingInfo.pack(bufStart);
  broadcastMessage(MsgShotBegin, (char *) buf - (char *) bufStart, bufStart);
  return shotId;
}
It basically just sends a "shot fired" packet to the server in a ways. (if I am not mistaken.)
So these days, all shots basically get the same effect and no longer is it possible to generate entirely different lasting shots, infinitely lasting bullets..etc

There is some clever trickery which could be used to adjust the amount of times a shot lasts, I'm assuming, but doing so will have a few unintended side effects and can't be ported towards shockwaves and lasers.(And it would be a hack basically.)
(Shockwaves and lasers are the only weapons which do not end a shot when it hits a tank.)

The handling of the shots:

Code: Select all

  float minRange = (float) bz_getBZDBDouble("_grenadeMinRange");
  float maxRange = (float) bz_getBZDBDouble("_grenadeMaxRange");
  float lifetime = (float) bz_getBZDBDouble("_grenadeTriggerTime");
  float duration = (float) bz_getBZDBDouble("_grenadeShockDuration");
This was done when we were able to adjust shot lifetimes and more.

References:
Shockwave death plug-in Before API change.

Code: Select all

void SWDeathHandler::Event ( bz_EventData *eventData )
{
  // We only handle the player death event, so bail out otherwise
  if (eventData->eventType != bz_ePlayerDieEvent)
    return;

  // Cast our event data so we can access the death position
  bz_PlayerDieEventData_V1 *dieData = (bz_PlayerDieEventData_V1*)eventData;

  // Retrieve the current reload time value
  float reloadTime = (float)bz_getBZDBDouble("_reloadTime");

  // If _swDeathReloadFactor is defined and greater than zero, multiply the
  // reload time by this factor
  if (bz_BZDBItemExists("_swDeathReloadFactor") && bz_getBZDBDouble("_swDeathReloadFactor") > 0)
    reloadTime *= (float)bz_getBZDBDouble("_swDeathReloadFactor");

  // Fire a shockwave where the player died
  bz_fireWorldWep("SW", reloadTime, BZ_SERVER, dieData->state.pos, 0, 0, 0, 0.0f);
}
Shockwave plug-in after API change.

Code: Select all

void SWDeathHandler::Event ( bz_EventData *eventData )
{
  // We only handle the player death event, so bail out otherwise
  if (eventData->eventType != bz_ePlayerDieEvent)
    return;

  // Cast our event data so we can access the death position
  bz_PlayerDieEventData_V1 *dieData = (bz_PlayerDieEventData_V1*)eventData;

  // Fire a shockwave where the player died
  float vector[3] = {0, 0, 0};
  bz_fireServerShot("SW", dieData->state.pos, vector);
}
Hopefully this provides a bit of insight into the API changes and explains a bit of things as well.

-Zehra
There's this game I love and it's called Ducati. ~Zehra
Those who are critical of me, I'll likely be the same of them. ~Zehra
There's always something to remember and it's been a game I love. ~Zehra
The time spent is a time which can never be regained, so it's a time to enjoy. ~Zehra
The decisions we make are the ones we look forward too and the ones we regret. ~Zehra
The details and the skill of knowing and applying them is what excellence is made of. ~Zehra
The best player is the one who knows what to do and when and applies it successfully. ~Zehra
There's a difference between knowing my name and knowing me, one shows respect to my name and the other is to who I am. ~Zehra
My blog is available at zehrahblog.wordpress.com.
See where I've last been active at Strayers.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest