[Setup]
Product=Team Damage
Version=120
Archive=teamdamage.umod
SrcPath=.
MasterPath=..
Group=SetupGroup
Group=teamdamageGroup
[SetupGroup]
Copy=(Src=System\Manifest.ini,Master=System\Manifest.ini,Size=315,Flags=3)
Copy=(Src=System\Manifest.int,Master=System\Manifest.int,Size=305,Flags=3)
[teamdamageGroup]
File=(Src=Help\teamdamage.html,Size=7243)
File=(Src=System\TeamDamage.u,Size=14558)
File=(Src=System\TeamDamage.int,Size=278)
[Setup]
LocalProduct=Team Damage
ReadMe=Help\teamdamage.html
SetupWindowTitle=Team Damage
AutoplayWindowTitle=Team Damage Options
ProductURL=http://www.planetunreal.com/tooreal
VersionURL=http://www.planetunreal.com/tooreal
Developer=Jeff McClain
DeveloperURL=http://www.planetunreal.com/tooreal
Team Damage Mutator for Unreal Tournament
Team Damage Mutator for Unreal Tournament
version 1.2
February 18, 2000
Installation Instructions:
Simply double click on the .umod file (which you may save pretty much anywhere you like) and Unreal Tournament should launch an installer and place all files in the proper place. PLEASE: be sure to click on the new MODS menu that shows up in your Unreal Tournament menu bar and configure your preferred settings. Also, this mutator only works if friendly fire is turned on!!!
Mutator Description (What it does):
Basically, I wanted to have a way to slow down some of the highly exciteable people out there that get trigger happy. Friendly fire, while realistic, and cool, sometimes proves to be very counter productive when playing with some of the people out there. So, I thought that it would be cool if servers could turn friendly fire back on, but have a way to penalize players who shoot everyone and everything.
So, what you have is a mutator that allows you to MIRROR the damage done to the "victim" team-mate back on the careless idiot spraying ammo. So when Team mate A shoots Team mate B, you can set it so that B gets 0 damage, and A gets all of the damage that he is dishing out (limited by the friendly fire percentage), or you can set it so that A only gets 75% of the damage, and B gets the other 25% (that way the whole team suffers). Basically if you set Damage Scaling to 100%, you would have your normal old play where the victim gets all the damage. If you set it at 0%, then you have the other extreme where the team fragger gets the whole enchilada.
The other side of this, is that I thought maybe it would be cool to actually play the savior if you could give some of your health to a needy team mate (say, the one carring the flag...grin). So you can enable "transferance" mode if you want. Basically this enables you to shoot your team mate, and take his damage upon yourself and give him the same amount of health back. Now, I also made this "transferance" ratio scalable too. Meaning that you can scale the amount of health that the victim gets for every point of damage that you take. A ratio of 1 would make your team mate victim get exactly the same amount of health that you take in damage when you shoot him. A ratio of 2 would make him only get 1 point of health for every 2 points of damage that you take from shooting him. Make sense? You can only boost a team mate to a max of 199 health, and if you only have 3 points of health left, then that is all that you could give your team mate after transferance ratios (no mater how much damage you hit him with, so forget about the redeemer).
The final portion of this, just added on some constructive coments by a friend, is a Conservation of Health modification. Basical, it says if the team mate is at 199 and you have transferance on, it will not impart any damage to you (as well as if you impart too much healing to push the team mate over 199, you will only impart the damage with the transferance ratio that is required to attain 199). That way, you can possibly heal a whole team with a redeemer shot, for example (if you have enough health and the transferance ratio is low enough). Additionally, I only let you impart as much health after transferance ratio as you have. In otherwords, you can't heal someone completely with a rocket shot if you only have 1 health left. Without Conservation of Health, there is no clamping done (you still take damage even after you've healed someone to 199 and you only transfer health that you have). Conservation of Health also limits the amount of Mirror damage you take if the target is almost dead anyway. Without this checked, you will take as much damage as you impart, regardless of the victim's health.
Making it work:
All you have to do is pick "mutators" from the Start Practice Match menu, and double click or drag the "Team Damage" mutator over to the right screen. A new menu should also appear on your Unreal Tournament main menu bar, called "MODS". Under this, you can fully customize the Team Damage for transferance ratio, transferance selection, and damage scaling. Note, you MUST have friendly fire on for this mutator to work
Notes:
This mutator works in all modes of Unreal Tournament, and I've tested it out on a server. Be aware that very large transferance ratios can kill you VERY quickly.
Credits/Thanks:
Many thanks to Tim Sweeny, Brandon Reinhart a.k.a. GreenMarine (brandon@epicgames.com), Jpb (jpb@planetunreal.com), Squidi (howard@mailer.fsu.edu), Bane (bane@unrealized.com) and planet Unreal (http://www.planetunreal.com) for all of the community development support. This is my first mutator, and it was a bit confusing, simply due to the lack of any real compiled source with good documentation.
I also spent god knows how much time trying to learn how to use ucc and fix some STUPID warnings in a default properties area simply because UCC didn't like SPACES or TABS between the variable and the equal signs, as well as it didn't like SEMICOLONS in the default prop area...stupid...
Disclaimer/Legal stuff:
Copyrite Jeff McClain, 2000. Don't use this for commercial/profit purposes without the author's express written consent. You are free to look at the code and use for learning purposes.
Send all comments, questions, etc. to jmcclain@micron.net
Release History:
v1.00 - Just coded it up in a day and released it (the menus take the longest for me).
v1.10 - Added option for Conservation of Health clamping.
v1.20 - Config settings will be saved to .ini file.
Improvements/Next version:
Possibly add new play modes. Would like to make the bots learn how to heal. Fix bugs if anyone reports them to jmcclain@micron.net
(C) Jeff McClain 2000
Page maintained by Jeff McClain, jmcclain@micron.net. Copyright(c) . Created: Monday, January 17, 2000 at 2:28:52 PM Updated: 2/18/00 at 6:52:12 AM
*E m @ ' 6 @ 4 \g `Ô ' m None SetText TeamDamage SetHelpText CreateControl Core System UWindow SetHelp SetValue GetValue SetRange
GetHumanName MutatorTakeDamage Engine Notify SplitDamage bConservationOfHealth TransferScaling TeamDamageConfigMenuItem TeamDamageConfigMenu Created MenuCaption MenuHelp Execute RegisterDamageMutator ClientClass TakeDamage PostBeginPlay TeamDamageConfigMenuCW UMenu WindowTitle Close UMutator D Function C DamageType Team
bIsPlayer Vector ScriptText E Health HitLocation Game Owner VictimName NextDamageMutator Victim Mutator bChecked Struct StaticSaveConfig
LevelInfo StructProperty ClassProperty Momentum
actualDamage Actor
instigatedBy
BoolProperty TextBuffer UWindowHSliderControl UWindowPulldownMenuItem UWindowSmallCloseButton UWindowDialogClientWindow UWindowFramedWindow UWindowClientWindow UWindowRootWindow UWindowCheckbox UWindowDialogControl UWindowWindow UWindowPulldownMenu
CreateWindow GameInfo HelpText
WinHeight WinWidth Root
bByParent CloseButton PlayerReplicationInfo Level StrProperty
NameProperty UMenuRootWindow UMenuStatusBar UMenuModMenuItem Initialized
StatusBar MenuItem Botpack
TeamGamePlus Pawn
ByteProperty Object Package Class bTransferance ObjectProperty FloatProperty IntProperty ShooterName TransferRatio TransferanceCheckBox ConservationCheckBox SplitDamageSlider TransferanceRatioSlider &! eِ l R ù 9} 9} 9} 9} 9} .; 9} .; 9} 9} 9} 9} 9} 9} 9} 9} 9} 9} 9} l R ù R ù $ >$ ?
@ @ @ @ @ @ @ %$ > Xr98 ~ |[$ eم eو |[$ |[$ eم eو |[$ eه |.Xڅ eم eه |.Xڅ eى im im {O ) im im {O eه |.Xڅ eم eم eه |.Xڇ |.Xڇ |.Xڅ eه |.Xڇ |.Xڇ |.Xڅ eو |[$ eو |[$ |[$ |[$ |[$ eو |[$ |[$ |[$! 2 b֪ M]TeamDamage Mutator Options
T//=============================================================================
// TeamDamageConfigMenuItem.
//=============================================================================
class TeamDamageConfigMenuItem expands UMenuModMenuItem;
// Called when the menu item is chosen
function Execute()
{
MenuItem.Owner.Root.CreateWindow(class'TeamDamageConfigMenu', 20, 20, 275, 125);
}
' 2 @I ͷ ;aG նm o ]TeamDamage Mutator Options ]+*Configure the TeamDamage Mutator options. x//=============================================================================
// TeamDamageConfigMenu.
//=============================================================================
class TeamDamageConfigMenu expands UWindowFramedWindow;
# . ?,0?, @B A. A A C ? Conservation of Health: R If checked, clamps health transferance and limits damage that can be done. - -
. %C A B ?
Transferance:
Q If checked, enables transfer of damage from shooter to health for target.
- -. A A zC ? @A&
?, '* ppTransferRatio [ U?,]: Z Set transfer cost ratio. Higher numbers mean it hurts more to help your team mate. . A pB zC ? B& D B
? '% ppSplit Damage [ S %]: M Split damage between shooter and victim (0% for no damage to victim). "
u oa ow * w *o - -
w o: : - D?
8 - D?
,- D? ,
,ǡ C D? ?. - D?D? ? # * # w*$
P --'N a 0 . q -
-
?, ? B - # : U
A
$
D
? B % ppSplit Damage [ S %]:
?, * ppTransferRatio [ U?,]:
Q
-
-
- -
?
$w.*w. *. ?
<$ 9w.*9w. *. ?
{=//=============================================================================
// TeamDamageConfigMenuCW.
//=============================================================================
class TeamDamageConfigMenuCW expands UWindowDialogClientWindow;
var int SplitDamage;
var float TransferRatio;
var UWindowSmallCloseButton CloseButton;
var UWindowCheckBox TransferanceCheckBox,ConservationCheckBox;
var UWindowHSliderControl SplitDamageSlider, TransferanceRatioSlider;
var class UMutator;
function Created()
{
Super.Created();
CloseButton = UWindowSmallCloseButton(CreateWindow(class'UWindowSmallCloseButton', WinWidth-48, WinHeight-19, 48, 16));
// Conservation of Health check box
ConservationCheckBox = UWindowCheckBox(CreateControl(class'UWindowCheckBox', 10,10,135,1));
ConservationCheckBox.SetText("Conservation of Health:");
ConservationCheckBox.SetHelpText("If checked, clamps health transferance and limits damage that can be done.");
ConservationCheckBox.bChecked = UMutator.default.bConservationOfHealth;
// Transferance check box
TransferanceCheckBox = UWindowCheckBox(CreateControl(class'UWindowCheckBox', 165,10,90,1));
TransferanceCheckBox.SetText("Transferance:");
TransferanceCheckBox.SetHelpText("If checked, enables transfer of damage from shooter to health for target.");
TransferanceCheckBox.bChecked = UMutator.default.bTransferance;
TransferanceRatioSlider=UWindowHSliderControl(CreateControl(class'UWindowHSliderControl', 10,30,250,1));
TransferanceRatioSlider.SetRange(0, 12, 1);
TransferRatio=UMutator.default.TransferScaling*4;
TransferanceRatioSlider.SetValue(TransferRatio,true);
TransferanceRatioSlider.SetText("TransferRatio ["$TransferRatio/4$"]:");
TransferanceRatioSlider.SetHelpText("Set transfer cost ratio. Higher numbers mean it hurts more to help your team mate.");
SplitDamageSlider=UWindowHSliderControl(CreateControl(class'UWindowHSliderControl', 10,60,250,1));
SplitDamageSlider.SetRange(0, 100, 1);
SplitDamage=UMutator.default.SplitDamage * 100.0;
SplitDamageSlider.SetValue(SplitDamage,true);
SplitDamageSlider.SetText("Split Damage ["$SplitDamage$"%]:");
SplitDamageSlider.SetHelpText("Split damage between shooter and victim (0% for no damage to victim).");
}
function Close(optional bool bByParent)
{
UMutator.default.bTransferance = TransferanceCheckBox.bChecked;
UMutator.default.TransferScaling = TransferRatio/4;
UMutator.default.SplitDamage = SplitDamage/100.0;
UMutator.static.StaticSaveConfig();
Super.Close(bByParent);
}
function Notify(UWindowDialogControl C, byte E)
{
Super.Notify(C, E);
switch(E) {
case DE_Change:
switch(C) {
case SplitDamageSlider:
SplitDamage=SplitDamageSlider.GetValue();
UMutator.default.SplitDamage=(SplitDamage/100.0);
UMutator.static.StaticSaveConfig();
SplitDamageSlider.SetText("Split Damage ["$SplitDamage$"%]:");
break;
case TransferanceRatioSlider:
TransferRatio=TransferanceRatioSlider.GetValue();
UMutator.default.TransferScaling = TransferRatio/4;
UMutator.static.StaticSaveConfig();
TransferanceRatioSlider.SetText("TransferRatio ["$TransferRatio/4$"]:");
break;
case TransferanceCheckBox:
UMutator.default.bTransferance = TransferanceCheckBox.bChecked;
UMutator.static.StaticSaveConfig();
break;
case ConservationCheckBox:
UMutator.default.bConservationOfHealth = ConservationCheckBox.bChecked;
UMutator.static.StaticSaveConfig();
break;
}
break;
case DE_MouseMove:
if(UMenuRootWindow(Root) != None)
if(UMenuRootWindow(Root).StatusBar != None)
UMenuRootWindow(Root).StatusBar.SetHelp(C.HelpText);
break;
case DE_MouseLeave:
if(UMenuRootWindow(Root) != None)
if(UMenuRootWindow(Root).StatusBar != None)
UMenuRootWindow(Root).StatusBar.SetHelp("");
break;
}
}
]4//=============================================================================
// TeamDamage.
// by Jeff McClain
// email: jmcclain@micron.net
//=============================================================================
class TeamDamage expands Mutator;
var config bool Initialized,bTransferance,bConservationOfHealth;
var config float SplitDamage,TransferScaling;
function PostBeginPlay()
{
if (Initialized)
{
return;
}
Initialized = True;
// Damage Mutator for TeamHits
if (ClassIsChildOf(Level.Game.class, class'TeamGamePlus') )
Level.Game.RegisterDamageMutator( Self );
}
// Damage Mutator function for TeamHits
function MutatorTakeDamage( out int ActualDamage, Pawn Victim, Pawn InstigatedBy, out Vector HitLocation, out Vector Momentum, name DamageType)
{
local int D;
local string ShooterName, VictimName;
if (ClassIsChildOf(Level.Game.class, class'TeamGamePlus')) {
if (InstigatedBy != None && Victim != None) {
if(InstigatedBy.bIsPlayer && Victim.bIsPlayer && InstigatedBy != Victim ) {
ShooterName = InstigatedBy.GetHumanName();
VictimName = Victim.GetHumanName();
if (InstigatedBy.PlayerReplicationInfo.Team == Victim.PlayerReplicationInfo.Team) {
if (bTransferance) {
D = ActualDamage*TransferScaling;
if ((D > InstigatedBy.Health) && bConservationOfHealth) { // Clamp max amount of Healing you can do to your max health.
D = InstigatedBy.Health;
ActualDamage = D/TransferScaling;
}
// log("Transferance Damage Delt ("$TransferScaling$"% Scaling):");
// log(" Victim, "$VictimName$", gained "$ActualDamage$" health from original "$Victim.Health);
Victim.Health += ActualDamage;
if (Victim.Health > 199) {
if (bConservationOfHealth)
D = (ActualDamage-(Victim.Health-199)) * TransferScaling;
Victim.Health = 199; // Clamp the "additional" amount to 199.
}
Victim.Health += ActualDamage; // Add it twice (since this one will actually get taken away)
} else {
D = ActualDamage*(1.0-SplitDamage);
if (((ActualDamage - D) > Victim.Health) && bConservationOfHealth) // Clamp max damage you take if Victim is almost dead
D = (Victim.Health/SplitDamage)*(1.0-SplitDamage);
// This is to offset the damage Victim will take in next normal "TakeDamage" pass-on call
// log("Mirror Damage Delt (Spliting "$SplitDamage$"% of "$ActualDamage$"):");
// log(" Victim, "$VictimName$", lost "$ActualDamage-D$" health from original "$Victim.Health);
Victim.Health += D;
}
// log(" Shooter, "$ShooterName$", lost "$D$" health from original "$InstigatedBy.Health);
InstigatedBy.TakeDamage(D, None, HitLocation, vect(0,0,0), DamageType);
}
}
}
}
if ( NextDamageMutator != None )
NextDamageMutator.MutatorTakeDamage( ActualDamage, Victim, InstigatedBy, HitLocation, Momentum, DamageType );
}
< <