Prepare fixtures
This commit is contained in:
parent
797e5ea192
commit
9c94356263
6021 changed files with 722805 additions and 22 deletions
274
kf_sources/NicePack/Classes/BitStreamReader.uc
Normal file
274
kf_sources/NicePack/Classes/BitStreamReader.uc
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
/**
|
||||
* Class for packaging various data types into an array of bytes.
|
||||
* Copyright 2020 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class BitStreamReader extends Object;
|
||||
|
||||
// Array of bytes to read from
|
||||
var private array<byte> stream;
|
||||
var private int currentBytePointer;
|
||||
var private int currentBitPointer;
|
||||
// Write `byte` from `stream[currentBytePointer]` to avoid unnecessary
|
||||
// array access calls.
|
||||
var private byte currentByte;
|
||||
|
||||
var private const array<byte> bitMask;
|
||||
var private const array<byte> bitMaskBefore;
|
||||
var private const array<byte> bitMaskAfter;
|
||||
|
||||
var private int tempInt;
|
||||
var private string tempString;
|
||||
var private byte temp;
|
||||
var private byte result;
|
||||
var private byte rightBoundary;
|
||||
var private byte remainingToRead;
|
||||
var private byte byte1, byte2, byte3, byte4;
|
||||
|
||||
public final function Initialize(array<byte> newStream)
|
||||
{
|
||||
stream = newStream;
|
||||
currentBytePointer = 0;
|
||||
currentBitPointer = 0;
|
||||
if (stream.length > 0) {
|
||||
currentByte = stream[0];
|
||||
}
|
||||
}
|
||||
|
||||
private final function ShiftBytePointer()
|
||||
{
|
||||
currentBitPointer = 0;
|
||||
currentBytePointer += 1;
|
||||
if (currentBytePointer < stream.length) {
|
||||
currentByte = stream[currentBytePointer];
|
||||
}
|
||||
else {
|
||||
currentByte = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public final function byte ReadBit()
|
||||
{
|
||||
if (currentBytePointer >= stream.length) return 0;
|
||||
if ((currentByte & bitMask[currentBitPointer]) > 0) {
|
||||
currentBitPointer += 1;
|
||||
if (currentBitPointer >= 8) {
|
||||
ShiftBytePointer();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
currentBitPointer += 1;
|
||||
if (currentBitPointer >= 8) {
|
||||
ShiftBytePointer();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public final function bool ReadBool()
|
||||
{
|
||||
if (currentBytePointer >= stream.length) return false;
|
||||
if ((currentByte & bitMask[currentBitPointer]) > 0) {
|
||||
currentBitPointer += 1;
|
||||
if (currentBitPointer >= 8) {
|
||||
ShiftBytePointer();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
currentBitPointer += 1;
|
||||
if (currentBitPointer >= 8) {
|
||||
ShiftBytePointer();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public final function byte ReadByte(optional int bitLimit)
|
||||
{
|
||||
if (currentBytePointer >= stream.length) return 0;
|
||||
// Default `bitLimit`
|
||||
if (bitLimit <= 0 || bitLimit > 8) {
|
||||
bitLimit = 8;
|
||||
}
|
||||
// Throw away already read part
|
||||
result = currentByte & bitMaskAfter[currentBitPointer];
|
||||
if (bitLimit <= 8 - currentBitPointer)
|
||||
{
|
||||
// If all we are asked to read is contained in cuurent `byte` -
|
||||
// just throw away excessive info by shifting to the right
|
||||
result = result >>> (8 - currentBitPointer - bitLimit);
|
||||
currentBitPointer += bitLimit;
|
||||
if (currentBitPointer >= 8) {
|
||||
ShiftBytePointer();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// Otherwise shift already read part up
|
||||
rightBoundary = bitLimit - (8 - currentBitPointer);
|
||||
result = result << rightBoundary;
|
||||
// Move to the next byte
|
||||
ShiftBytePointer();
|
||||
currentBitPointer = rightBoundary;
|
||||
// Record required part from the second byte
|
||||
temp = currentByte & bitMaskBefore[rightBoundary];
|
||||
temp = temp >>> (8 - rightBoundary);
|
||||
result = result | temp;
|
||||
return result;
|
||||
}
|
||||
|
||||
public final function int ReadInt(optional int bitLimit)
|
||||
{
|
||||
// Default `bitLimit`
|
||||
if (bitLimit <= 0 || bitLimit > 32) {
|
||||
bitLimit = 32;
|
||||
}
|
||||
byte1 = ReadByte(bitLimit);
|
||||
if (bitLimit <= 8) {
|
||||
return byte1;
|
||||
}
|
||||
bitLimit -= 8;
|
||||
byte2 = ReadByte(bitLimit);
|
||||
if (bitLimit <= 8)
|
||||
{
|
||||
tempInt = byte1 << bitLimit;
|
||||
tempInt = tempInt | byte2;
|
||||
return tempInt;
|
||||
}
|
||||
bitLimit -= 8;
|
||||
byte3 = ReadByte(bitLimit);
|
||||
if (bitLimit <= 8)
|
||||
{
|
||||
tempInt = byte1 << (bitLimit + 8);
|
||||
tempInt = tempInt | (byte2 << bitLimit);
|
||||
tempInt = tempInt | byte3;
|
||||
return tempInt;
|
||||
}
|
||||
bitLimit -= 8;
|
||||
byte4 = ReadByte(bitLimit);
|
||||
tempInt = byte1 << (bitLimit + 16);
|
||||
tempInt = tempInt | (byte2 << (bitLimit + 8));
|
||||
tempInt = tempInt | (byte3 << bitLimit);
|
||||
tempInt = tempInt | byte4;
|
||||
return tempInt;
|
||||
}
|
||||
|
||||
public final function float ReadFloat(
|
||||
int precisionLevel,
|
||||
optional byte bitLimit)
|
||||
{
|
||||
if (bitLimit < 0 || bitLimit > 32) {
|
||||
bitLimit = 32;
|
||||
}
|
||||
precisionLevel = Max(0, precisionLevel);
|
||||
return float(ReadInt(bitLimit)) * (0.1 ** precisionLevel);
|
||||
}
|
||||
|
||||
public final function string ReadString(int length)
|
||||
{
|
||||
if (length <= 0) return "";
|
||||
while (length > 0)
|
||||
{
|
||||
length -= 1;
|
||||
tempString $= Chr(ReadByte());
|
||||
}
|
||||
return tempString;
|
||||
}
|
||||
|
||||
// String representation of `class`es has a more limited character range,
|
||||
// which allows us to fit every chgaracter in `class`' name into 6 bits,
|
||||
// saving 25% space.
|
||||
// Allowed characters are: digits, upper and lower case letters, dot '.'
|
||||
// and underscore '_'.
|
||||
// Any other symbol is converted into an underscore.
|
||||
private final function byte CompressClassCharacter(byte source)
|
||||
{
|
||||
// 26 upper case character
|
||||
if (source >= 65 && source <= 90) {
|
||||
return source - 65;
|
||||
}
|
||||
// 26 lower case character // 52 total
|
||||
if (source >= 97 && source <= 122) {
|
||||
return 26 + (source - 97);
|
||||
}
|
||||
// 10 digits // 62 total
|
||||
if (source >= 48 && source <= 57) {
|
||||
return 52 + (source - 48);
|
||||
}
|
||||
// dot
|
||||
if (source == 46) {
|
||||
return 62;
|
||||
}
|
||||
// underscore and everything else
|
||||
return 63;
|
||||
}
|
||||
|
||||
private final function byte DecompressClassCharacter(byte source)
|
||||
{
|
||||
if (source >= 63) return 95;
|
||||
// 26 upper case character
|
||||
if (source <= 25) {
|
||||
return source + 65;
|
||||
}
|
||||
// 26 lower case character
|
||||
if (source <= 51) {
|
||||
return source + 71;
|
||||
}
|
||||
// 10 digits
|
||||
if (source <= 61) {
|
||||
return source - 4;
|
||||
}
|
||||
// dot
|
||||
// if (source == 62)
|
||||
return 46;
|
||||
}
|
||||
|
||||
public final function string ReadClassName(int length)
|
||||
{
|
||||
if (length <= 0) return "";
|
||||
while (length > 0)
|
||||
{
|
||||
length -= 1;
|
||||
tempString $= Chr(DecompressClassCharacter(ReadByte(6)));
|
||||
}
|
||||
return tempString;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bitMask(0) = 128 // 1 0 0 0 0 0 0 0
|
||||
bitMask(1) = 64 // 0 1 0 0 0 0 0 0
|
||||
bitMask(2) = 32 // 0 0 1 0 0 0 0 0
|
||||
bitMask(3) = 16 // 0 0 0 1 0 0 0 0
|
||||
bitMask(4) = 8 // 0 0 0 0 1 0 0 0
|
||||
bitMask(5) = 4 // 0 0 0 0 0 1 0 0
|
||||
bitMask(6) = 2 // 0 0 0 0 0 0 1 0
|
||||
bitMask(7) = 1 // 0 0 0 0 0 0 0 1
|
||||
bitMaskBefore(0) = 128 // 1 0 0 0 0 0 0 0
|
||||
bitMaskBefore(1) = 192 // 1 1 0 0 0 0 0 0
|
||||
bitMaskBefore(2) = 224 // 1 1 1 0 0 0 0 0
|
||||
bitMaskBefore(3) = 240 // 1 1 1 1 0 0 0 0
|
||||
bitMaskBefore(4) = 248 // 1 1 1 1 1 0 0 0
|
||||
bitMaskBefore(5) = 252 // 1 1 1 1 1 1 0 0
|
||||
bitMaskBefore(6) = 254 // 1 1 1 1 1 1 1 0
|
||||
bitMaskBefore(7) = 255 // 1 1 1 1 1 1 1 1
|
||||
bitMaskAfter(0) = 255 // 1 1 1 1 1 1 1 1
|
||||
bitMaskAfter(1) = 127 // 0 1 1 1 1 1 1 1
|
||||
bitMaskAfter(2) = 63 // 0 0 1 1 1 1 1 1
|
||||
bitMaskAfter(3) = 31 // 0 0 0 1 1 1 1 1
|
||||
bitMaskAfter(4) = 15 // 0 0 0 0 1 1 1 1
|
||||
bitMaskAfter(5) = 7 // 0 0 0 0 0 1 1 1
|
||||
bitMaskAfter(6) = 3 // 0 0 0 0 0 0 1 1
|
||||
bitMaskAfter(7) = 1 // 0 0 0 0 0 0 0 1
|
||||
}
|
||||
352
kf_sources/NicePack/Classes/BitStreamWriter.uc
Normal file
352
kf_sources/NicePack/Classes/BitStreamWriter.uc
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
/**
|
||||
* Class for packaging various data types into an array of bytes.
|
||||
* Copyright 2020 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class BitStreamWriter extends Object;
|
||||
|
||||
// Array of fully written bytes
|
||||
var private array<byte> stream;
|
||||
// Last byte that still has some space to fit data into.
|
||||
// We start writing data into it's least significant bits and shift them up
|
||||
// when we want to write more data inside or when we are asked to return
|
||||
// recorded data.
|
||||
var private byte unfinishedByte;
|
||||
// How much space is left in `unfinishedByte`
|
||||
var private byte bitsLeft;
|
||||
|
||||
// Can be used to erase unnecessary bits from a byte
|
||||
var private const array<byte> bitMaskAfter;
|
||||
|
||||
// We'll declare all auxiliary variables as globals to avoid their
|
||||
// unnecessary creation inside functions, to make them more lightweight.
|
||||
var private byte shift, altShift;
|
||||
var private byte temp;
|
||||
var private int tempInt;
|
||||
var private byte byte1, byte2, byte3, byte4;
|
||||
|
||||
/**
|
||||
* Resets contents of the `BitStreamWriter`, making it the same as a
|
||||
* brand new writer.
|
||||
*
|
||||
* @return `BitStreamWriter` to allow for function chaining.
|
||||
*/
|
||||
public final function BitStreamWriter InitializeStream()
|
||||
{
|
||||
stream.length = 0;
|
||||
unfinishedByte = 0;
|
||||
bitsLeft = 8;
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records a bit inside a `BitStreamWriter`.
|
||||
*
|
||||
* @param source Byte that defines a bit. We don't look at any actual bits in
|
||||
* `source`'s representation, but simply consired the bit to be
|
||||
* `1` if `source > 0` and `0` if `source == 0`.
|
||||
* @return `BitStreamWriter` to allow for function chaining.
|
||||
*/
|
||||
public final function BitStreamWriter WriteBit(byte source)
|
||||
{
|
||||
unfinishedByte = unfinishedByte << 1;
|
||||
if (source > 0) {
|
||||
unfinishedByte += 1;
|
||||
}
|
||||
bitsLeft -= 1;
|
||||
if (bitsLeft <= 0) {
|
||||
stream[stream.length] = unfinishedByte;
|
||||
unfinishedByte = 0;
|
||||
bitsLeft = 8;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records a bit inside a `BitStreamWriter`.
|
||||
*
|
||||
* @param source Boolean value that defines a bit. `true` means bit is equal
|
||||
* to `1` and `false` means that it is equal to `0`.
|
||||
* @return `BitStreamWriter` to allow for function chaining.
|
||||
*/
|
||||
public final function BitStreamWriter WriteBoolean(bool isOne)
|
||||
{
|
||||
unfinishedByte = unfinishedByte << 1;
|
||||
if (isOne) {
|
||||
unfinishedByte += 1;
|
||||
}
|
||||
// Update storage
|
||||
bitsLeft -= 1;
|
||||
if (bitsLeft <= 0) {
|
||||
stream[stream.length] = unfinishedByte;
|
||||
unfinishedByte = 0;
|
||||
bitsLeft = 8;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records a `byte` inside a `BitStreamWriter`.
|
||||
*
|
||||
* @param source Boolean value that defines a bit. `true` means bit is
|
||||
* equal to `1` and `false` means that it is equal to `0`.
|
||||
* @param bitLimit How many of the (least significant) bits to record;
|
||||
* can be used to compress values that don't need the full `byte`
|
||||
* value range.
|
||||
* @return `BitStreamWriter` to allow for function chaining.
|
||||
*/
|
||||
public final function BitStreamWriter WriteByte(
|
||||
byte source,
|
||||
optional byte bitLimit)
|
||||
{
|
||||
// Default `bitLimit`
|
||||
if (bitLimit < 0 || bitLimit > 8) {
|
||||
bitLimit = 8;
|
||||
}
|
||||
// Zero unnecessary bits
|
||||
source = source & bitMaskAfter[8 - bitLimit];
|
||||
if (bitLimit < bitsLeft)
|
||||
{
|
||||
// We have enough space to fit all the bits in `unfinishedByte`
|
||||
unfinishedByte = unfinishedByte << bitLimit;
|
||||
unfinishedByte = unfinishedByte | source;
|
||||
// Update storage
|
||||
bitsLeft -= bitLimit;
|
||||
if (bitsLeft <= 0)
|
||||
{
|
||||
stream[stream.length] = unfinishedByte;
|
||||
unfinishedByte = 0;
|
||||
bitsLeft = 8;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
// If we don't have enough space, - record what can fit in
|
||||
// current `unfinishedByte`
|
||||
unfinishedByte = unfinishedByte << bitsLeft;
|
||||
altShift = bitLimit - bitsLeft;
|
||||
temp = source >>> altShift;
|
||||
unfinishedByte = unfinishedByte | temp;
|
||||
// And add it to the storage
|
||||
stream[stream.length] = unfinishedByte;
|
||||
// Create new byte by erasing recorded bits from the `source`
|
||||
temp = temp << altShift;
|
||||
unfinishedByte = source ^ temp;
|
||||
bitsLeft = 8 - altShift;
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records an `int` inside a `BitStreamWriter`.
|
||||
*
|
||||
* @param source Integer value to record into `BitStreamWriter`.
|
||||
* @param bitLimit How many of the (least significant) bits to record;
|
||||
* can be used to compress values that don't need the full `int`
|
||||
* value range.
|
||||
* @return `BitStreamWriter` to allow for function chaining.
|
||||
*/
|
||||
public final function BitStreamWriter WriteInt(
|
||||
int source,
|
||||
optional byte bitLimit)
|
||||
{
|
||||
// Default `bitLimit`
|
||||
if (bitLimit == 0) {
|
||||
bitLimit = 32;
|
||||
}
|
||||
byte1 = byte((source & 0xff000000) >>> 24);
|
||||
byte2 = byte((source & 0x00ff0000) >>> 16);
|
||||
byte3 = byte((source & 0x0000ff00) >>> 8);
|
||||
byte4 = source & 0x000000ff;
|
||||
if (bitLimit > 24) {
|
||||
WriteByte(byte1, bitLimit - 24);
|
||||
}
|
||||
if (bitLimit > 16) {
|
||||
WriteByte(byte2, bitLimit - 16);
|
||||
}
|
||||
if (bitLimit > 8) {
|
||||
WriteByte(byte3, bitLimit - 8);
|
||||
}
|
||||
WriteByte(byte4, bitLimit);
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records an `float` inside a `BitStreamWriter`.
|
||||
*
|
||||
* `floats` can only be recorded with a specified amount of decimal places.
|
||||
* This is because we can't really get precise float bit representation or
|
||||
* easily truncate it's value bit-wise, so we multiply it by a specified
|
||||
* power of 10 and then transfer integer part of the result as `int`.
|
||||
* Specified precision level IS NOT recorded into `BitStreamWriter`.
|
||||
*
|
||||
* @param source Integer value to record into `BitStreamWriter`.
|
||||
* @param precisionLevel How many decimal places after the dot to record.
|
||||
* @param bitLimit How many of the (least significant) bits to record;
|
||||
* can be used to compress values that don't need the full value range of
|
||||
* truncated float.
|
||||
* @return `BitStreamWriter` to allow for function chaining.
|
||||
*/
|
||||
public final function BitStreamWriter WriteFloat(
|
||||
float source,
|
||||
int precisionLevel,
|
||||
optional byte bitLimit)
|
||||
{
|
||||
if (bitLimit < 0 || bitLimit > 32) {
|
||||
bitLimit = 32;
|
||||
}
|
||||
precisionLevel = Max(0, precisionLevel);
|
||||
tempInt = int(Round( source * (10 ** precisionLevel) ));
|
||||
WriteInt(tempInt, bitLimit);
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records an `string` inside a `BitStreamWriter`, treating each code point as
|
||||
* a byte, which will lead to loss of data when recording `string`s that
|
||||
* contain code points with values `> 255`.
|
||||
*
|
||||
* Does not record `string`'s length or where it ends.
|
||||
*
|
||||
* @param source `string` value to record into `BitStreamWriter`.
|
||||
* @return `BitStreamWriter` to allow for function chaining.
|
||||
*/
|
||||
public final function BitStreamWriter WriteString(string source)
|
||||
{
|
||||
while (source != "")
|
||||
{
|
||||
WriteByte(Asc(source));
|
||||
source = Mid(0, 1);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records an string representation of a `class` name inside
|
||||
* a `BitStreamWriter`, compressing it's characters to 6 bit representation.
|
||||
*
|
||||
* Allowed characters are: digits, upper and lower case letters, dot '.'
|
||||
* and underscore '_'.
|
||||
* Any other character will be converted into underscore.
|
||||
*
|
||||
* Does not record `string`'s length or where it ends.
|
||||
*
|
||||
* @param source String representation of a `class`' name value to record
|
||||
* into `BitStreamWriter`.
|
||||
* @return `BitStreamWriter` to allow for function chaining.
|
||||
*/
|
||||
public final function BitStreamWriter WriteClassName(string source)
|
||||
{
|
||||
while (source != "")
|
||||
{
|
||||
WriteByte(CompressClassCharacter(Asc(source)), 6);
|
||||
source = Mid(source, 1);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
// String representation of `class`es has a more limited character range,
|
||||
// which allows us to fit every chgaracter in `class`' name into 6 bits,
|
||||
// saving 25% space.
|
||||
// Allowed characters are: digits, upper and lower case letters, dot '.'
|
||||
// and underscore '_'.
|
||||
// Any other symbol is converted into an underscore.
|
||||
private final function byte CompressClassCharacter(byte source)
|
||||
{
|
||||
// 26 upper case character
|
||||
if (source >= 65 && source <= 90) {
|
||||
return source - 65;
|
||||
}
|
||||
// 26 lower case character // 52 total
|
||||
if (source >= 97 && source <= 122) {
|
||||
return 26 + (source - 97);
|
||||
}
|
||||
// 10 digits // 62 total
|
||||
if (source >= 48 && source <= 57) {
|
||||
return 52 + (source - 48);
|
||||
}
|
||||
// dot
|
||||
if (source == 46) {
|
||||
return 62;
|
||||
}
|
||||
// underscore (`95`) and everything else
|
||||
return 63;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all data recorded so far in a caller `BitStreamWriter` as
|
||||
* an array of bytes. Data is written ion order, starting from bytes with
|
||||
* lesser indecies and their most significant bits.
|
||||
*
|
||||
* @return Array of bytes that contains all data written into caller
|
||||
* `BitStreamWriter`.
|
||||
*/
|
||||
public final function array<byte> GetData()
|
||||
{
|
||||
local array<byte> result;
|
||||
result = stream;
|
||||
if (bitsLeft < 8) {
|
||||
result[result.length] = unfinishedByte << bitsLeft;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns amount of data (in bits) recorded into caller `BitStreamWriter`.
|
||||
*
|
||||
* @return Amount (in bits) of recorded data.
|
||||
*/
|
||||
public final function int GetSize()
|
||||
{
|
||||
local int sizeInBits;
|
||||
sizeInBits = stream.length * 8;
|
||||
if (bitsLeft < 8) {
|
||||
sizeInBits += (8 - bitsLeft);
|
||||
}
|
||||
return sizeInBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns amount of data (in bytes) recorded into caller `BitStreamWriter`.
|
||||
*
|
||||
* @param onlyFullBytes Only count filled bytes, i.e. if last byte only has
|
||||
* 5 bits (or any amount `<8`) of info written in it -
|
||||
* method will not count it.
|
||||
* @return Amount (in bytes) of recorded data.
|
||||
*/
|
||||
public final function int GetSizeInBytes(optional bool onlyFullBytes)
|
||||
{
|
||||
local int sizeInBytes;
|
||||
sizeInBytes = stream.length;
|
||||
if (!onlyFullBytes && bitsLeft < 8) {
|
||||
sizeInBytes += 1;
|
||||
}
|
||||
return sizeInBytes;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
// With this we do not need to call `Initialize` to use a newly created
|
||||
// `BitStreamWriter`
|
||||
bitsLeft = 8
|
||||
bitMaskAfter(0) = 255 // 1 1 1 1 1 1 1 1
|
||||
bitMaskAfter(1) = 127 // 0 1 1 1 1 1 1 1
|
||||
bitMaskAfter(2) = 63 // 0 0 1 1 1 1 1 1
|
||||
bitMaskAfter(3) = 31 // 0 0 0 1 1 1 1 1
|
||||
bitMaskAfter(4) = 15 // 0 0 0 0 1 1 1 1
|
||||
bitMaskAfter(5) = 7 // 0 0 0 0 0 1 1 1
|
||||
bitMaskAfter(6) = 3 // 0 0 0 0 0 0 1 1
|
||||
bitMaskAfter(7) = 1 // 0 0 0 0 0 0 0 1
|
||||
}
|
||||
67
kf_sources/NicePack/Classes/MeanBleedInventory.uc
Normal file
67
kf_sources/NicePack/Classes/MeanBleedInventory.uc
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
class MeanBleedInventory extends Inventory;
|
||||
|
||||
|
||||
const dmtype_bleed=class'NiceDamTypeStalkerBleed';
|
||||
var int maxBleedCount;
|
||||
var private float fBleedPeriod;
|
||||
|
||||
var int bleedLevel;
|
||||
var MeanZombieStalker stalker;
|
||||
|
||||
|
||||
event PostBeginPlay()
|
||||
{
|
||||
super.PostBeginPlay();
|
||||
// start the timer
|
||||
SetTimer(fBleedPeriod, true);
|
||||
}
|
||||
|
||||
|
||||
event Timer()
|
||||
{
|
||||
local pawn locpawn;
|
||||
local bool amAlive;
|
||||
local int bleedDamage;
|
||||
|
||||
locpawn = Pawn(Owner);
|
||||
amAlive = locpawn != none && locpawn.Health > 0;
|
||||
|
||||
bleedDamage = bleedLevel * 7;
|
||||
// if pawn owner is dead or bleed count is done - destroy
|
||||
if (!amAlive || maxBleedCount < 0 || bleedDamage < 1.0)
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
maxBleedCount--;
|
||||
|
||||
if (stalker != none)
|
||||
locpawn.TakeDamage(bleedDamage, stalker, locpawn.Location,
|
||||
vect(0, 0, 0), dmtype_bleed);
|
||||
else
|
||||
locpawn.TakeDamage(bleedDamage, locpawn, locpawn.Location,
|
||||
vect(0, 0, 0), dmtype_bleed);
|
||||
|
||||
if (locpawn.isA('KFPawn'))
|
||||
{
|
||||
KFPawn(locpawn).HealthToGive -= 2 * bleedLevel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// cleanup
|
||||
function Destroyed()
|
||||
{
|
||||
if (stalker != none)
|
||||
stalker = none;
|
||||
|
||||
super.Destroyed();
|
||||
}
|
||||
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
maxBleedCount=7
|
||||
fBleedPeriod=1.500000
|
||||
}
|
||||
60
kf_sources/NicePack/Classes/MeanHuskFireProjectile.uc
Normal file
60
kf_sources/NicePack/Classes/MeanHuskFireProjectile.uc
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
class MeanHuskFireProjectile extends NiceHuskFireProjectile;
|
||||
simulated singular function Touch(Actor Other){
|
||||
local vector HitLocation, HitNormal;
|
||||
//Don't touch bulletwhip attachment. Taken from HuskFireProjectile
|
||||
if ( Other == none || KFBulletWhipAttachment(Other) != none )
|
||||
return;
|
||||
if ( Other.bProjTarget || Other.bBlockActors ) {
|
||||
LastTouched = Other;
|
||||
if ( Velocity == vect(0,0,0) || Other.IsA('Mover') ) {
|
||||
ProcessTouch(Other,Location);
|
||||
LastTouched = none;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( Other.TraceThisActor(HitLocation, HitNormal, Location, Location - 2*Velocity, GetCollisionExtent()) )
|
||||
HitLocation = Location;
|
||||
|
||||
ProcessTouch(Other, HitLocation);
|
||||
LastTouched = none;
|
||||
if ( (Role < ROLE_Authority) && (Other.Role == ROLE_Authority) && (Pawn(Other) != none) )
|
||||
ClientSideTouch(Other, HitLocation);
|
||||
}
|
||||
}
|
||||
// Don't hit Zed extra collision cylinders
|
||||
simulated function ProcessTouch(Actor Other, Vector HitLocation) {
|
||||
// Don't let it hit this player, or blow up on another player
|
||||
if (Other == none || Other == Instigator || Other.Base == Instigator)
|
||||
return;
|
||||
// Don't collide with bullet whip attachments
|
||||
if (KFBulletWhipAttachment(Other) != none) {
|
||||
return;
|
||||
}
|
||||
// Use the instigator's location if it exists. This fixes issues with
|
||||
// the original location of the projectile being really far away from
|
||||
// the real Origloc due to it taking a couple of milliseconds to
|
||||
// replicate the location to the client and the first replicated location has
|
||||
// already moved quite a bit.
|
||||
if (Instigator != none) {
|
||||
OrigLoc = Instigator.Location;
|
||||
}
|
||||
if (!bDud && ((VSizeSquared(Location - OrigLoc) < ArmDistSquared) || OrigLoc == vect(0,0,0))) {
|
||||
if( Role == ROLE_Authority ) {
|
||||
AmbientSound=none;
|
||||
PlaySound(Sound'ProjectileSounds.PTRD_deflect04',,2.0);
|
||||
Other.TakeDamage( ImpactDamage, Instigator, HitLocation, Normal(Velocity), ImpactDamageType );
|
||||
}
|
||||
|
||||
bDud = true;
|
||||
Velocity = vect(0,0,0);
|
||||
LifeSpan=1.0;
|
||||
SetPhysics(PHYS_Falling);
|
||||
}
|
||||
if (!bDud) {
|
||||
Explode(HitLocation,Normal(HitLocation-Other.Location));
|
||||
}
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
additionalDamagePart=0.250000
|
||||
}
|
||||
24
kf_sources/NicePack/Classes/MeanPoisonInventory.uc
Normal file
24
kf_sources/NicePack/Classes/MeanPoisonInventory.uc
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
class MeanPoisonInventory extends Inventory;
|
||||
var float poisonStartTime, maxSpeedPenaltyTime, poisonSpeedDown;
|
||||
simulated function Tick(float DeltaTime) {
|
||||
if(Level.TimeSeconds - poisonStartTime > maxSpeedPenaltyTime)
|
||||
Destroy();
|
||||
}
|
||||
simulated function float GetMovementModifierFor(Pawn InPawn){
|
||||
local float actualSpeedDown;
|
||||
local class<NiceVeterancyTypes> niceVet;
|
||||
|
||||
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(InPawn.PlayerReplicationInfo);
|
||||
if(niceVet != none){
|
||||
actualSpeedDown = 1.0 - (1.0 - poisonSpeedDown) * niceVet.static.SlowingModifier(KFPlayerReplicationInfo(InPawn.PlayerReplicationInfo));
|
||||
actualSpeedDown = FMax(0.0, FMin(1.0, actualSpeedDown));
|
||||
return actualSpeedDown;
|
||||
}
|
||||
// If something went wrong - ignore slowdown altogether
|
||||
return 1.0;
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
maxSpeedPenaltyTime=5.000000
|
||||
poisonSpeedDown=0.800000
|
||||
}
|
||||
4
kf_sources/NicePack/Classes/MeanReplicationInfo.uc
Normal file
4
kf_sources/NicePack/Classes/MeanReplicationInfo.uc
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
// no use atm
|
||||
class MeanReplicationInfo extends ReplicationInfo;
|
||||
|
||||
defaultproperties{}
|
||||
91
kf_sources/NicePack/Classes/MeanVoting.uc
Normal file
91
kf_sources/NicePack/Classes/MeanVoting.uc
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
class MeanVoting extends ScrnVotingOptions;
|
||||
var NicePack Mut;
|
||||
function int GetGroupVoteIndex(PlayerController Sender, string Group, string Key, out string Value, out string VoteInfo)
|
||||
{
|
||||
local int ZedNumber;
|
||||
local int BoolValue;
|
||||
local bool bEnable;
|
||||
ZedNumber = Mut.ZedNumber(Key);
|
||||
BoolValue = TryStrToBool(Value);
|
||||
if(BoolValue == -1)
|
||||
return VOTE_ILLEGAL;
|
||||
bEnable = (BoolValue == 1);
|
||||
if(Key ~= "ALL")
|
||||
return 0;
|
||||
if (ZedNumber == -1)
|
||||
return VOTE_UNKNOWN;
|
||||
if(bEnable == Mut.ZedDatabase[ZedNumber].bNeedsReplacement)
|
||||
return VOTE_NOEFECT;
|
||||
else
|
||||
return ZedNumber + 1;
|
||||
return VOTE_UNKNOWN;
|
||||
}
|
||||
function ApplyVoteValue(int VoteIndex, string VoteValue)
|
||||
{
|
||||
local int i;
|
||||
local int BoolValue;
|
||||
local bool bEnable;
|
||||
local bool bAffectsAll;
|
||||
bAffectsAll = false;
|
||||
if(VoteIndex == 0)
|
||||
bAffectsAll = true;
|
||||
else
|
||||
VoteIndex --;
|
||||
BoolValue = TryStrToBool(VoteValue);
|
||||
if ( BoolValue == -1 )
|
||||
return;
|
||||
bEnable = (BoolValue == 1);
|
||||
if(!bAffectsAll)
|
||||
Mut.ZedDatabase[VoteIndex].bNeedsReplacement = bEnable;
|
||||
else{
|
||||
for(i = 0; i <= Mut.lastStandardZed;i ++)
|
||||
Mut.ZedDatabase[i].bNeedsReplacement = bEnable;
|
||||
}
|
||||
if(Mut.ZedDatabase[VoteIndex].ZedName ~= "CLOT" || bAffectsAll)
|
||||
Mut.bReplaceClot = bEnable;
|
||||
if(Mut.ZedDatabase[VoteIndex].ZedName ~= "CRAWLER" || bAffectsAll)
|
||||
Mut.bReplaceCrawler = bEnable;
|
||||
if(Mut.ZedDatabase[VoteIndex].ZedName ~= "STALKER" || bAffectsAll)
|
||||
Mut.bReplaceStalker = bEnable;
|
||||
if(Mut.ZedDatabase[VoteIndex].ZedName ~= "GOREFAST" || bAffectsAll)
|
||||
Mut.bReplaceGorefast = bEnable;
|
||||
if(Mut.ZedDatabase[VoteIndex].ZedName ~= "BLOAT" || bAffectsAll)
|
||||
Mut.bReplaceBloat = bEnable;
|
||||
if(Mut.ZedDatabase[VoteIndex].ZedName ~= "SIREN" || bAffectsAll)
|
||||
Mut.bReplaceSiren = bEnable;
|
||||
if(Mut.ZedDatabase[VoteIndex].ZedName ~= "HUSK" || bAffectsAll)
|
||||
Mut.bReplaceHusk = bEnable;
|
||||
if(Mut.ZedDatabase[VoteIndex].ZedName ~= "SCRAKE" || bAffectsAll)
|
||||
Mut.bReplaceScrake = bEnable;
|
||||
if(Mut.ZedDatabase[VoteIndex].ZedName ~= "FLESHPOUND" || bAffectsAll)
|
||||
Mut.bReplaceFleshpound = bEnable;
|
||||
Mut.SaveConfig();
|
||||
VotingHandler.BroadcastMessage(strRestartRequired);
|
||||
}
|
||||
function SendGroupHelp(PlayerController Sender, string Group)
|
||||
{
|
||||
local string s;
|
||||
local int i;
|
||||
local int ln;
|
||||
ln = 1;
|
||||
s $= "ALL";
|
||||
for ( i=0; i <= Mut.lastStandardZed; ++i ) {
|
||||
if ( Mut.ZedDatabase[i].bNeedsReplacement )
|
||||
s @= "%g";
|
||||
else
|
||||
s @= "%r";
|
||||
s $= Caps(Mut.ZedDatabase[i].ZedName); if ( len(s) > 80 ) {
|
||||
// move to new line
|
||||
GroupInfo[ln++] = VotingHandler.ParseHelpLine(default.GroupInfo[1] @ s);
|
||||
s = "";
|
||||
} }
|
||||
GroupInfo[ln] = VotingHandler.ParseHelpLine(default.GroupInfo[1] @ s);
|
||||
super.SendGroupHelp(Sender, Group);
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
DefaultGroup="MEAN"
|
||||
HelpInfo(0)="%pMEAN %y<zed_name> %gON%w|%rOFF %w Add|Remove mean zeds from the game. Type %bMVOTE MEAN HELP %w for more info."
|
||||
GroupInfo(0)="%MEAN %y<zed_name> %gON%w|%rOFF %w Add or remove mean zeds from the game."
|
||||
GroupInfo(1)="%wAvaliable mean zeds:"
|
||||
}
|
||||
88
kf_sources/NicePack/Classes/MeanZombieBloat.uc
Normal file
88
kf_sources/NicePack/Classes/MeanZombieBloat.uc
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
class MeanZombieBloat extends NiceZombieBloat;
|
||||
#exec OBJ LOAD FILE=MeanZedSkins.utx
|
||||
/**
|
||||
* bAmIBarfing true if the bloat is in the barf animation
|
||||
*/
|
||||
var bool bAmIBarfing;
|
||||
/**
|
||||
* bileCoolDownTimer timer that counts to when the bloat will spawn another set of pile pellets
|
||||
* bileCoolDownMax max time in between pellet spawns
|
||||
*/
|
||||
var float bileCoolDownTimer,bileCoolDownMax;
|
||||
/**
|
||||
* Spawn extra sets of bile pellets here once the bile cool down timer
|
||||
* has reached the max limit
|
||||
*/
|
||||
simulated function Tick(float DeltaTime) {
|
||||
Super.Tick(DeltaTime);
|
||||
if(!bDecapitated && bAmIBarfing) {
|
||||
bileCoolDownTimer+= DeltaTime;
|
||||
if(bileCoolDownTimer >= bileCoolDownMax) {
|
||||
SpawnTwoShots();
|
||||
bileCoolDownTimer= 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Touch(Actor Other)
|
||||
{
|
||||
if (Other == none)
|
||||
return;
|
||||
|
||||
super.Touch(Other);
|
||||
if (Other.IsA('ShotgunBullet'))
|
||||
{
|
||||
ShotgunBullet(Other).Damage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function RangedAttack(Actor A) {
|
||||
local int LastFireTime;
|
||||
if ( bShotAnim )
|
||||
return;
|
||||
if ( Physics == PHYS_Swimming ) {
|
||||
SetAnimAction('Claw');
|
||||
bShotAnim = true;
|
||||
LastFireTime = Level.TimeSeconds;
|
||||
}
|
||||
else if ( VSize(A.Location - Location) < MeleeRange + CollisionRadius + A.CollisionRadius ) {
|
||||
bShotAnim = true;
|
||||
LastFireTime = Level.TimeSeconds;
|
||||
SetAnimAction('Claw');
|
||||
//PlaySound(sound'Claw2s', SLOT_Interact); KFTODO: Replace this
|
||||
Controller.bPreparingMove = true;
|
||||
Acceleration = vect(0,0,0);
|
||||
}
|
||||
else if ( (KFDoorMover(A) != none || VSize(A.Location-Location) <= 250) && !bDecapitated ) {
|
||||
bShotAnim = true;
|
||||
SetAnimAction('ZombieBarfMoving');
|
||||
RunAttackTimeout = GetAnimDuration('ZombieBarf', 1.0);
|
||||
bMovingPukeAttack=true;
|
||||
|
||||
// Randomly send out a message about Bloat Vomit burning(3% chance)
|
||||
if ( FRand() < 0.03 && KFHumanPawn(A) != none && PlayerController(KFHumanPawn(A).Controller) != none ) {
|
||||
PlayerController(KFHumanPawn(A).Controller).Speech('AUTO', 7, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
//ZombieBarf animation triggers this
|
||||
function SpawnTwoShots() {
|
||||
super.SpawnTwoShots();
|
||||
bAmIBarfing= true;
|
||||
}
|
||||
simulated function AnimEnd(int Channel) {
|
||||
local name Sequence;
|
||||
local float Frame, Rate;
|
||||
|
||||
GetAnimParams( ExpectingChannel, Sequence, Frame, Rate );
|
||||
super.AnimEnd(Channel);
|
||||
if(Sequence == 'ZombieBarf')
|
||||
bAmIBarfing= false;
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
bileCoolDownMax=0.750000
|
||||
HeadHealth=125.000000
|
||||
MenuName="Mean Bloat"
|
||||
Skins(0)=Combiner'MeanZedSkins.bloat_cmb'
|
||||
}
|
||||
19
kf_sources/NicePack/Classes/MeanZombieClot.uc
Normal file
19
kf_sources/NicePack/Classes/MeanZombieClot.uc
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
class MeanZombieClot extends NiceZombieClot;
|
||||
#exec OBJ LOAD FILE=MeanZedSkins.utx
|
||||
function int ModBodyDamage(out int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class<NiceWeaponDamageType> damageType, float headshotLevel, KFPlayerReplicationInfo KFPRI, optional float lockonTime){
|
||||
local bool bDecreaseDamage;
|
||||
// Decrease damage if needed
|
||||
bDecreaseDamage = false;
|
||||
if(damageType != none)
|
||||
bDecreaseDamage = (headshotLevel <= 0.0) && damageType.default.bCheckForHeadShots;
|
||||
if(damageType != none && damageType.default.heatPart > 0)
|
||||
bDecreaseDamage = false;
|
||||
if(bDecreaseDamage && HeadHealth > 0)
|
||||
Damage *= 0.5;
|
||||
return super.ModBodyDamage(Damage, instigatedBy, hitlocation, momentum, damageType, headshotLevel, KFPRI, lockonTime);
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
MenuName="Mean Clot"
|
||||
Skins(0)=Combiner'MeanZedSkins.clot_cmb'
|
||||
}
|
||||
55
kf_sources/NicePack/Classes/MeanZombieCrawler.uc
Normal file
55
kf_sources/NicePack/Classes/MeanZombieCrawler.uc
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
class MeanZombieCrawler extends NiceZombieCrawler;
|
||||
#exec OBJ LOAD FILE=MeanZedSkins.utx
|
||||
simulated function PostBeginPlay() {
|
||||
super.PostBeginPlay();
|
||||
PounceSpeed = Rand(221)+330;
|
||||
MeleeRange = Rand(41)+50;
|
||||
}
|
||||
/**
|
||||
* Copied from ZombieCrawler.Bump() but changed damage type
|
||||
* to be the new poison damage type
|
||||
*/
|
||||
event Bump(actor Other) {
|
||||
if(bPouncing && KFHumanPawn(Other) != none)
|
||||
Poison(KFHumanPawn(Other));
|
||||
super.Bump(Other);
|
||||
}
|
||||
function bool MeleeDamageTarget(int hitdamage, vector pushdir) {
|
||||
local bool result;
|
||||
result= super.MeleeDamageTarget(hitdamage, pushdir);
|
||||
if(result && KFHumanPawn(Controller.Target) != none)
|
||||
Poison(KFHumanPawn(Controller.Target));
|
||||
return result;
|
||||
}
|
||||
|
||||
function Poison(KFHumanPawn poisonedPawn)
|
||||
{
|
||||
local Inventory I;
|
||||
local bool bFoundPoison;
|
||||
|
||||
if (poisonedPawn.Inventory != none)
|
||||
{
|
||||
for (I = poisonedPawn.Inventory; I != none; I = I.Inventory)
|
||||
{
|
||||
if (MeanPoisonInventory(I) != none)
|
||||
{
|
||||
bFoundPoison = true;
|
||||
MeanPoisonInventory(I).poisonStartTime = Level.TimeSeconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!bFoundPoison)
|
||||
{
|
||||
I = Controller.Spawn(class<Inventory>(DynamicLoadObject(string(class'MeanPoisonInventory'), class'Class')));
|
||||
MeanPoisonInventory(I).poisonStartTime = Level.TimeSeconds;
|
||||
I.GiveTo(poisonedPawn);
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
GroundSpeed=190.000000
|
||||
WaterSpeed=175.000000
|
||||
MenuName="Mean Crawler"
|
||||
Skins(0)=Combiner'MeanZedSkins.crawler_cmb'
|
||||
}
|
||||
101
kf_sources/NicePack/Classes/MeanZombieFleshPound.uc
Normal file
101
kf_sources/NicePack/Classes/MeanZombieFleshPound.uc
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
class MeanZombieFleshPound extends NiceZombieFleshPound;
|
||||
#exec OBJ LOAD FILE=MeanZedSkins.utx
|
||||
state RageCharging
|
||||
{
|
||||
Ignores StartChargingFP;
|
||||
function bool CanGetOutOfWay()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Don't override speed in this state
|
||||
function bool CanSpeedAdjust()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
function BeginState()
|
||||
{
|
||||
bChargingPlayer = true;
|
||||
if( Level.NetMode!=NM_DedicatedServer )
|
||||
ClientChargingAnims();
|
||||
|
||||
RageEndTime = (Level.TimeSeconds + 15) + (FRand() * 18);
|
||||
NetUpdateTime = Level.TimeSeconds - 1;
|
||||
}
|
||||
function EndState()
|
||||
{
|
||||
bChargingPlayer = false;
|
||||
bFrustrated = false;
|
||||
if(Controller != none)
|
||||
NiceZombieFleshPoundController(Controller).RageFrustrationTimer = 0;
|
||||
|
||||
if( Level.NetMode!=NM_DedicatedServer )
|
||||
ClientChargingAnims();
|
||||
|
||||
NetUpdateTime = Level.TimeSeconds - 1;
|
||||
}
|
||||
simulated function UpdateGroundSpeed() {
|
||||
super(NiceMonster).UpdateGroundSpeed();
|
||||
if (!bShotAnim) {
|
||||
groundSpeed *= 2.3;
|
||||
}
|
||||
}
|
||||
function Tick( float Delta )
|
||||
{
|
||||
// Keep the flesh pound moving toward its target when attacking
|
||||
if( Role == ROLE_Authority && bShotAnim)
|
||||
{
|
||||
if( LookTarget!=none )
|
||||
{
|
||||
Acceleration = AccelRate * Normal(LookTarget.Location - Location);
|
||||
}
|
||||
}
|
||||
|
||||
global.Tick(Delta);
|
||||
}
|
||||
function Bump( Actor Other )
|
||||
{
|
||||
local float RageBumpDamage;
|
||||
local KFMonster KFMonst;
|
||||
|
||||
KFMonst = KFMonster(Other);
|
||||
|
||||
// Hurt/Kill enemies that we run into while raging
|
||||
if( !bShotAnim && KFMonst!=none && NiceZombieFleshPound(Other)==none && Pawn(Other).Health>0 )
|
||||
{
|
||||
// Random chance of doing obliteration damage
|
||||
if( FRand() < 0.4 )
|
||||
{
|
||||
RageBumpDamage = 501;
|
||||
}
|
||||
else
|
||||
{
|
||||
RageBumpDamage = 450;
|
||||
}
|
||||
|
||||
RageBumpDamage *= KFMonst.PoundRageBumpDamScale;
|
||||
|
||||
Other.TakeDamage(RageBumpDamage, self, Other.Location, Velocity * Other.Mass, class'NiceDamTypePoundCrushed');
|
||||
}
|
||||
else Global.Bump(Other);
|
||||
}
|
||||
// If fleshie hits his target on a charge, then he should settle down for abit.
|
||||
function bool MeleeDamageTarget(int hitdamage, vector pushdir)
|
||||
{
|
||||
local bool RetVal,bWasEnemy;
|
||||
|
||||
bWasEnemy = (Controller.Target==Controller.Enemy);
|
||||
RetVal = Super(NiceMonster).MeleeDamageTarget(hitdamage*1.75, pushdir*3);
|
||||
// Only stop if you've successfully killed your target
|
||||
if(Pawn(Controller.Target) == none)
|
||||
return RetVal;
|
||||
if( KFPawn(Controller.Target) != none && Pawn(Controller.Target).Health <= 0 && RetVal && bWasEnemy ){
|
||||
GoToState('');
|
||||
}
|
||||
return RetVal;
|
||||
}
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
MenuName="Mean FleshPound"
|
||||
Skins(0)=Combiner'MeanZedSkins.fleshpound_cmb'
|
||||
}
|
||||
40
kf_sources/NicePack/Classes/MeanZombieGorefast.uc
Normal file
40
kf_sources/NicePack/Classes/MeanZombieGorefast.uc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
class MeanZombieGorefast extends NiceZombieGorefast;
|
||||
#exec OBJ LOAD FILE=MeanZedSkins.utx
|
||||
var float minRageDist;
|
||||
function bool IsStunPossible(){
|
||||
return false;
|
||||
}
|
||||
function RangedAttack(Actor A) {
|
||||
Super(NiceMonster).RangedAttack(A);
|
||||
if(!bShotAnim && !bDecapitated && VSize(A.Location-Location) <= minRageDist)
|
||||
GoToState('RunningState');
|
||||
}
|
||||
state RunningState {
|
||||
function RangedAttack(Actor A){
|
||||
if(bShotAnim || Physics == PHYS_Swimming)
|
||||
return;
|
||||
else if(CanAttack(A)){
|
||||
bShotAnim = true;
|
||||
|
||||
//Always do the charging melee attack
|
||||
SetAnimAction('ClawAndMove');
|
||||
RunAttackTimeout = GetAnimDuration('GoreAttack1', 1.0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Begin:
|
||||
GoTo('CheckCharge');
|
||||
CheckCharge:
|
||||
if(Controller != none && Controller.Target != none && VSize(Controller.Target.Location - Location) < minRageDist){
|
||||
Sleep(0.5 + FRand() * 0.5);
|
||||
GoTo('CheckCharge');
|
||||
}
|
||||
else
|
||||
GoToState('');
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
minRageDist=1400.000000
|
||||
MenuName="Mean Gorefast"
|
||||
Skins(0)=Combiner'MeanZedSkins.gorefast_cmb'
|
||||
}
|
||||
57
kf_sources/NicePack/Classes/MeanZombieHusk.uc
Normal file
57
kf_sources/NicePack/Classes/MeanZombieHusk.uc
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
class MeanZombieHusk extends NiceZombieHusk;
|
||||
#exec OBJ LOAD FILE=NicePackT.utx
|
||||
var int consecutiveShots, totalShots, maxNormalShots;
|
||||
|
||||
function DoStun(optional Pawn instigatedBy, optional Vector hitLocation, optional Vector momentum, optional class<NiceWeaponDamageType> damageType, optional float headshotLevel, optional KFPlayerReplicationInfo KFPRI){
|
||||
super.DoStun(instigatedBy, hitLocation, momentum, damageType, headshotLevel, KFPRI);
|
||||
totalShots = maxNormalShots;
|
||||
}
|
||||
|
||||
function RangedAttack(Actor A) {
|
||||
local int LastFireTime;
|
||||
if ( bShotAnim )
|
||||
return;
|
||||
if ( Physics == PHYS_Swimming ) {
|
||||
SetAnimAction('Claw');
|
||||
bShotAnim = true;
|
||||
LastFireTime = Level.TimeSeconds;
|
||||
}
|
||||
else if ( VSize(A.Location - Location) < MeleeRange + CollisionRadius + A.CollisionRadius ) {
|
||||
bShotAnim = true;
|
||||
LastFireTime = Level.TimeSeconds;
|
||||
SetAnimAction('Claw');
|
||||
//PlaySound(sound'Claw2s', SLOT_Interact); KFTODO: Replace this
|
||||
Controller.bPreparingMove = true;
|
||||
Acceleration = vect(0,0,0);
|
||||
}
|
||||
else if((KFDoorMover(A) != none ||
|
||||
(!Region.Zone.bDistanceFog && VSize(A.Location-Location) <= 65535) ||
|
||||
(Region.Zone.bDistanceFog && VSizeSquared(A.Location-Location) < (Square(Region.Zone.DistanceFogEnd) * 0.8))) // Make him come out of the fog a bit
|
||||
&& !bDecapitated && Physics != PHYS_Falling) {
|
||||
bShotAnim = true;
|
||||
|
||||
SetAnimAction('ShootBurns');
|
||||
Controller.bPreparingMove = true;
|
||||
Acceleration = vect(0,0,0);
|
||||
|
||||
//Increment the number of consecutive shtos taken and apply the cool down if needed
|
||||
totalShots ++;
|
||||
consecutiveShots ++;
|
||||
if(consecutiveShots < 3 && totalShots > maxNormalShots && VSize(a.location - location) <= 900)
|
||||
NextFireProjectileTime = Level.TimeSeconds;
|
||||
else{
|
||||
NextFireProjectileTime = Level.TimeSeconds + ProjectileFireInterval + (FRand() * 2.0);
|
||||
consecutiveShots = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
maxNormalShots=3
|
||||
AmmunitionClass=class'MeanZombieHuskAmmo'
|
||||
remainingStuns=1
|
||||
MenuName="Mean Husk"
|
||||
ControllerClass=class'MeanZombieHuskController'
|
||||
Skins(0)=Texture'NicePackT.MonsterMeanHusk.burns_tatters'
|
||||
Skins(1)=Shader'NicePackT.MonsterMeanHusk.burns_shdr'
|
||||
}
|
||||
7
kf_sources/NicePack/Classes/MeanZombieHuskAmmo.uc
Normal file
7
kf_sources/NicePack/Classes/MeanZombieHuskAmmo.uc
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
class MeanZombieHuskAmmo extends NiceZombieHuskAmmo;
|
||||
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
ProjectileClass=class'MeanHuskFireProjectile'
|
||||
}
|
||||
193
kf_sources/NicePack/Classes/MeanZombieHuskController.uc
Normal file
193
kf_sources/NicePack/Classes/MeanZombieHuskController.uc
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
class MeanZombieHuskController extends NiceZombieHuskController;
|
||||
var float aimAtFeetZDelta;
|
||||
function bool DefendMelee(float Dist) {
|
||||
return (Dist < 1000);
|
||||
}
|
||||
function rotator AdjustAim(FireProperties FiredAmmunition, vector projStart, int aimerror) {
|
||||
local rotator FireRotation, TargetLook;
|
||||
local float FireDist, TargetDist, ProjSpeed;
|
||||
local actor HitActor;
|
||||
local vector FireSpot, FireDir, TargetVel, HitLocation, HitNormal;
|
||||
local int realYaw;
|
||||
local bool bDefendCloseRange, bClean, bLeadTargetNow;
|
||||
local bool bWantsToAimAtFeet;
|
||||
if ( FiredAmmunition.ProjectileClass != none )
|
||||
projspeed = FiredAmmunition.ProjectileClass.default.speed;
|
||||
// make sure bot has a valid target
|
||||
if ( Target == none ) {
|
||||
Target = Enemy;
|
||||
if ( Target == none )
|
||||
return Rotation;
|
||||
}
|
||||
FireSpot = Target.Location;
|
||||
TargetDist = VSize(Target.Location - Pawn.Location);
|
||||
// perfect aim at stationary objects
|
||||
if ( Pawn(Target) == none ) {
|
||||
if ( !FiredAmmunition.bTossed )
|
||||
return rotator(Target.Location - projstart);
|
||||
else {
|
||||
FireDir = AdjustToss(projspeed,ProjStart,Target.Location,true);
|
||||
SetRotation(Rotator(FireDir));
|
||||
return Rotation;
|
||||
}
|
||||
}
|
||||
bLeadTargetNow = FiredAmmunition.bLeadTarget && bLeadTarget;
|
||||
bDefendCloseRange = ( (Target == Enemy) && DefendMelee(TargetDist) );
|
||||
aimerror = AdjustAimError(aimerror,TargetDist,bDefendCloseRange,FiredAmmunition.bInstantHit, bLeadTargetNow);
|
||||
// lead target with non instant hit projectiles
|
||||
if ( bLeadTargetNow ) {
|
||||
TargetVel = Target.Velocity;
|
||||
// hack guess at projecting falling velocity of target
|
||||
if ( Target.Physics == PHYS_Falling) {
|
||||
if ( Target.PhysicsVolume.Gravity.Z <= Target.PhysicsVolume.Default.Gravity.Z ) {
|
||||
TargetVel.Z = FMin(TargetVel.Z + FMax(-400, Target.PhysicsVolume.Gravity.Z * FMin(1,TargetDist/projSpeed)),0);
|
||||
} else {
|
||||
TargetVel.Z = FMin(0, TargetVel.Z);
|
||||
}
|
||||
}
|
||||
// more or less lead target (with some random variation)
|
||||
FireSpot += FMin(1, 0.7 + 0.6 * FRand()) * TargetVel * TargetDist/projSpeed;
|
||||
FireSpot.Z = FMin(Target.Location.Z, FireSpot.Z);
|
||||
/**
|
||||
* If the target is within 1000uu, offset the Z coordinate of the
|
||||
* FireSpot vector with aimAtFeetZDelta. Otherwise, the husk will
|
||||
* aim at behind the target, not at his feet.
|
||||
*/
|
||||
if (aimAtFeetZDelta != 0.0 && Target.Physics == PHYS_Falling && bDefendCloseRange) {
|
||||
FireSpot.Z= Pawn.Location.Z + aimAtFeetZDelta;
|
||||
}
|
||||
|
||||
if ( (Target.Physics != PHYS_Falling) && (FRand() < 0.55) && (VSize(FireSpot - ProjStart) > 1000) ) {
|
||||
// don't always lead far away targets, especially if they are moving sideways with respect to the bot
|
||||
TargetLook = Target.Rotation;
|
||||
if ( Target.Physics == PHYS_Walking )
|
||||
TargetLook.Pitch = 0;
|
||||
bClean = ( ((Vector(TargetLook) Dot Normal(Target.Velocity)) >= 0.71) && FastTrace(FireSpot, ProjStart) );
|
||||
}
|
||||
else // make sure that bot isn't leading into a wall
|
||||
bClean = FastTrace(FireSpot, ProjStart);
|
||||
if ( !bClean) {
|
||||
// reduce amount of leading
|
||||
if ( FRand() < 0.3 )
|
||||
FireSpot = Target.Location;
|
||||
else
|
||||
FireSpot = 0.5 * (FireSpot + Target.Location);
|
||||
}
|
||||
}
|
||||
bClean = false; //so will fail first check unless shooting at feet
|
||||
// Randomly determine if we should try and splash damage with the fire projectile
|
||||
if( FiredAmmunition.bTrySplash ) {
|
||||
if( Skill < 2.0 ) {
|
||||
if(FRand() > 0.85) {
|
||||
bWantsToAimAtFeet = true;
|
||||
}
|
||||
}
|
||||
else if( Skill < 3.0 ) {
|
||||
if(FRand() > 0.5) {
|
||||
bWantsToAimAtFeet = true;
|
||||
}
|
||||
}
|
||||
else if( Skill >= 3.0 ) {
|
||||
if(FRand() > 0.25) {
|
||||
bWantsToAimAtFeet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( FiredAmmunition.bTrySplash && (Pawn(Target) != none) && (((Target.Physics == PHYS_Falling)
|
||||
&& (Pawn.Location.Z + 80 >= Target.Location.Z)) || ((Pawn.Location.Z + 19 >= Target.Location.Z)
|
||||
&& (bDefendCloseRange || bWantsToAimAtFeet))) ) {
|
||||
HitActor = Trace(HitLocation, HitNormal, FireSpot - vect(0,0,1) * (Target.CollisionHeight + 10), FireSpot, false);
|
||||
|
||||
bClean = (HitActor == none);
|
||||
//So if we're too close, and not jumping, bClean is false
|
||||
//same distance but jumping, bClean is true
|
||||
if ( !bClean ) {
|
||||
FireSpot = HitLocation + vect(0,0,3);
|
||||
bClean = FastTrace(FireSpot, ProjStart);
|
||||
}
|
||||
else
|
||||
bClean = ( (Target.Physics == PHYS_Falling) && FastTrace(FireSpot, ProjStart) );
|
||||
/**
|
||||
* Update the aimAtFeetZDelta variable with the appropriate offset
|
||||
* once the Husk decides to aim at the target's feet. Update the
|
||||
* default property so all Super Husks can access it
|
||||
*/
|
||||
if (bClean && TargetDist > 625.0) {
|
||||
aimAtFeetZDelta= FireSpot.Z - Pawn.Location.Z;
|
||||
}
|
||||
}
|
||||
if ( !bClean ) {
|
||||
//try middle
|
||||
FireSpot.Z = Target.Location.Z;
|
||||
bClean = FastTrace(FireSpot, ProjStart);
|
||||
}
|
||||
if ( FiredAmmunition.bTossed && !bClean && bEnemyInfoValid ) {
|
||||
FireSpot = LastSeenPos;
|
||||
HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
|
||||
if ( HitActor != none ) {
|
||||
bCanFire = false;
|
||||
FireSpot += 2 * Target.CollisionHeight * HitNormal;
|
||||
}
|
||||
bClean = true;
|
||||
}
|
||||
if( !bClean ) {
|
||||
// try head
|
||||
FireSpot.Z = Target.Location.Z + 0.9 * Target.CollisionHeight;
|
||||
bClean = FastTrace(FireSpot, ProjStart);
|
||||
}
|
||||
if ( !bClean && (Target == Enemy) && bEnemyInfoValid ) {
|
||||
FireSpot = LastSeenPos;
|
||||
if ( Pawn.Location.Z >= LastSeenPos.Z )
|
||||
FireSpot.Z -= 0.4 * Enemy.CollisionHeight;
|
||||
HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
|
||||
if ( HitActor != none ) {
|
||||
FireSpot = LastSeenPos + 2 * Enemy.CollisionHeight * HitNormal;
|
||||
if ( Monster(Pawn).SplashDamage() && (Skill >= 4) ) {
|
||||
HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
|
||||
if ( HitActor != none )
|
||||
FireSpot += 2 * Enemy.CollisionHeight * HitNormal;
|
||||
}
|
||||
bCanFire = false;
|
||||
}
|
||||
}
|
||||
// adjust for toss distance
|
||||
if ( FiredAmmunition.bTossed ) {
|
||||
FireDir = AdjustToss(projspeed,ProjStart,FireSpot,true);
|
||||
}
|
||||
else {
|
||||
FireDir = FireSpot - ProjStart;
|
||||
}
|
||||
FireRotation = Rotator(FireDir);
|
||||
realYaw = FireRotation.Yaw;
|
||||
InstantWarnTarget(Target,FiredAmmunition,vector(FireRotation));
|
||||
FireRotation.Yaw = SetFireYaw(FireRotation.Yaw + aimerror);
|
||||
FireDir = vector(FireRotation);
|
||||
// avoid shooting into wall
|
||||
FireDist = FMin(VSize(FireSpot-ProjStart), 400);
|
||||
FireSpot = ProjStart + FireDist * FireDir;
|
||||
HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
|
||||
if ( HitActor != none ) {
|
||||
if ( HitNormal.Z < 0.7 ) {
|
||||
FireRotation.Yaw = SetFireYaw(realYaw - aimerror);
|
||||
FireDir = vector(FireRotation);
|
||||
FireSpot = ProjStart + FireDist * FireDir;
|
||||
HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
|
||||
}
|
||||
if ( HitActor != none ) {
|
||||
FireSpot += HitNormal * 2 * Target.CollisionHeight;
|
||||
if ( Skill >= 4 ) {
|
||||
HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
|
||||
if ( HitActor != none )
|
||||
FireSpot += Target.CollisionHeight * HitNormal;
|
||||
}
|
||||
FireDir = Normal(FireSpot - ProjStart);
|
||||
FireRotation = rotator(FireDir);
|
||||
}
|
||||
}
|
||||
//Make it so the Husk always shoots the ground it the target is close
|
||||
SetRotation(FireRotation);
|
||||
return FireRotation;
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
}
|
||||
47
kf_sources/NicePack/Classes/MeanZombieScrake.uc
Normal file
47
kf_sources/NicePack/Classes/MeanZombieScrake.uc
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
class MeanZombieScrake extends NiceZombieScrake;
|
||||
#exec OBJ LOAD FILE=MeanZedSkins.utx
|
||||
function RangedAttack(Actor A){
|
||||
Super.RangedAttack(A);
|
||||
if(!bShotAnim){
|
||||
if(bConfusedState)
|
||||
return;
|
||||
if(float(Health) / HealthMax < 0.75 || lastStunTime >= 0.0){
|
||||
MovementAnims[0] = 'ChargeF';
|
||||
GoToState('RunningState');
|
||||
}
|
||||
}
|
||||
}
|
||||
simulated event SetAnimAction(name NewAction){
|
||||
if(Role < Role_AUTHORITY && NewAction == 'ChargeF')
|
||||
PlayAnim('ChargeF', GetOriginalGroundSpeed() * 3.5);
|
||||
else
|
||||
super.SetAnimAction(NewAction);
|
||||
}
|
||||
simulated function Unstun(){
|
||||
bCharging = true;
|
||||
MovementAnims[0] = 'ChargeF';
|
||||
GoToState('RunningState');
|
||||
super.Unstun();
|
||||
}
|
||||
function TakeDamageClient(int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<NiceWeaponDamageType> damageType, float headshotLevel, float lockonTime){
|
||||
Super.TakeDamageClient(Damage, instigatedBy, hitLocation, momentum, damageType, headshotLevel, lockonTime);
|
||||
if(bIsStunned && Health > 0 && (headshotLevel <= 0.0) && Level.TimeSeconds > LastStunTime + 0.1)
|
||||
Unstun();
|
||||
}
|
||||
function TakeFireDamage(int Damage, Pawn Instigator){
|
||||
Super.TakeFireDamage(Damage, Instigator);
|
||||
if(bIsStunned && Health > 0 && Damage > 150 && Level.TimeSeconds > LastStunTime + 0.1)
|
||||
Unstun();
|
||||
}
|
||||
function bool CheckMiniFlinch(int flinchScore, Pawn instigatedBy, Vector hitLocation, Vector momentum, class<NiceWeaponDamageType> damageType, float headshotLevel, KFPlayerReplicationInfo KFPRI){
|
||||
if((ClassIsChildOf(damageType, class 'DamTypeMelee') || ClassIsChildOf(damageType, class 'NiceDamageTypeVetBerserker'))
|
||||
&& !KFPRI.ClientVeteranSkill.Static.CanMeleeStun() && (headshotLevel <= 0.0) && flinchScore < 250)
|
||||
return false;
|
||||
return super.CheckMiniFlinch(flinchScore, instigatedBy, hitLocation, momentum, damageType, headshotLevel, KFPRI);
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
MenuName="Mean Scrake"
|
||||
Skins(0)=Shader'MeanZedSkins.scrake_FB'
|
||||
Skins(1)=TexPanner'MeanZedSkins.scrake_saw_panner'
|
||||
}
|
||||
10
kf_sources/NicePack/Classes/MeanZombieSiren.uc
Normal file
10
kf_sources/NicePack/Classes/MeanZombieSiren.uc
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
class MeanZombieSiren extends NiceZombieSiren;
|
||||
#exec OBJ LOAD FILE=MeanZedSkins.utx
|
||||
defaultproperties
|
||||
{
|
||||
ScreamRadius=800
|
||||
ScreamForce=-200000
|
||||
MenuName="Mean Siren"
|
||||
Skins(0)=FinalBlend'MeanZedSkins.siren_hair_fb'
|
||||
Skins(1)=Combiner'MeanZedSkins.siren_cmb'
|
||||
}
|
||||
275
kf_sources/NicePack/Classes/MeanZombieStalker.uc
Normal file
275
kf_sources/NicePack/Classes/MeanZombieStalker.uc
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
class MeanZombieStalker extends NiceZombieStalker;
|
||||
#exec OBJ LOAD FILE=MeanZedSkins.utx
|
||||
simulated function Tick(float DeltaTime)
|
||||
{
|
||||
Super(NiceMonster).Tick(DeltaTime);
|
||||
if(Role == ROLE_Authority && bShotAnim && !bWaitForAnim){
|
||||
if( LookTarget!=none ) {
|
||||
Acceleration = AccelRate * Normal(LookTarget.Location - Location);
|
||||
}
|
||||
}
|
||||
if(Level.NetMode == NM_DedicatedServer)
|
||||
return; // Servers aren't interested in this info.
|
||||
if(bZapped){
|
||||
// Make sure we check if we need to be cloaked as soon as the zap wears off
|
||||
NextCheckTime = Level.TimeSeconds;
|
||||
}
|
||||
else if( Level.TimeSeconds > NextCheckTime && Health > 0 )
|
||||
{
|
||||
NextCheckTime = Level.TimeSeconds + 0.5;
|
||||
|
||||
if(LocalKFHumanPawn != none && LocalKFHumanPawn.Health > 0 && LocalKFHumanPawn.ShowStalkers() &&
|
||||
VSizeSquared(Location - LocalKFHumanPawn.Location) < LocalKFHumanPawn.GetStalkerViewDistanceMulti() * 640000.0) // 640000 = 800 Units
|
||||
bSpotted = True;
|
||||
else
|
||||
bSpotted = false;
|
||||
|
||||
if(!bSpotted && !bCloaked && Skins[0] != Combiner'MeanZedSkins.stalker_cmb')
|
||||
UncloakStalker();
|
||||
else if (Level.TimeSeconds - LastUncloakTime > 1.2){
|
||||
// if we're uberbrite, turn down the light
|
||||
if( bSpotted && Skins[0] != Finalblend'KFX.StalkerGlow' ){
|
||||
bUnlit = false;
|
||||
CloakStalker();
|
||||
}
|
||||
else if(Skins[0] != Shader'MeanZedSkins.stalker_invisible')
|
||||
CloakStalker();
|
||||
}
|
||||
}
|
||||
}
|
||||
simulated function CloakStalker()
|
||||
{
|
||||
// No cloaking if zapped
|
||||
if( bZapped )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( bSpotted )
|
||||
{
|
||||
if( Level.NetMode == NM_DedicatedServer )
|
||||
return;
|
||||
|
||||
Skins[0] = Finalblend'KFX.StalkerGlow';
|
||||
Skins[1] = Finalblend'KFX.StalkerGlow';
|
||||
bUnlit = true;
|
||||
return;
|
||||
}
|
||||
if ( !bDecapitated ) // No head, no cloak, honey. updated : Being charred means no cloak either :D Not.
|
||||
{
|
||||
Visibility = 1;
|
||||
bCloaked = true;
|
||||
|
||||
if( Level.NetMode == NM_DedicatedServer )
|
||||
Return;
|
||||
|
||||
Skins[0] = Shader'MeanZedSkins.stalker_invisible';
|
||||
Skins[1] = Shader'MeanZedSkins.stalker_invisible';
|
||||
|
||||
// Invisible - no shadow
|
||||
if(PlayerShadow != none)
|
||||
PlayerShadow.bShadowActive = false;
|
||||
if(RealTimeShadow != none)
|
||||
RealTimeShadow.Destroy();
|
||||
|
||||
// Remove/disallow projectors on invisible people
|
||||
Projectors.Remove(0, Projectors.Length);
|
||||
bAcceptsProjectors = false;
|
||||
SetOverlayMaterial(Material'KFX.FBDecloakShader', 0.25, true);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function UnCloakStalker()
|
||||
{
|
||||
if (bZapped)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!bCrispified)
|
||||
{
|
||||
LastUncloakTime = Level.TimeSeconds;
|
||||
|
||||
Visibility = default.Visibility;
|
||||
bCloaked = false;
|
||||
bUnlit = false;
|
||||
|
||||
// 25% chance of our Enemy saying something about us being invisible
|
||||
// added Controller check here
|
||||
if (Level.NetMode!=NM_Client && !KFGameType(Level.Game).bDidStalkerInvisibleMessage && FRand()<0.25 && Controller != none && Controller.Enemy!=none &&
|
||||
PlayerController(Controller.Enemy.Controller)!=none)
|
||||
{
|
||||
PlayerController(Controller.Enemy.Controller).Speech('AUTO', 17, "");
|
||||
KFGameType(Level.Game).bDidStalkerInvisibleMessage = true;
|
||||
}
|
||||
if( Level.NetMode == NM_DedicatedServer )
|
||||
Return;
|
||||
|
||||
if ( Skins[0] != Combiner'MeanZedSkins.stalker_cmb' )
|
||||
{
|
||||
Skins[1] = FinalBlend'MeanZedSkins.stalker_fb';
|
||||
Skins[0] = Combiner'MeanZedSkins.stalker_cmb';
|
||||
|
||||
if (PlayerShadow != none)
|
||||
PlayerShadow.bShadowActive = true;
|
||||
|
||||
bAcceptsProjectors = true;
|
||||
|
||||
SetOverlayMaterial(Material'KFX.FBDecloakShader', 0.25, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function SetZappedBehavior()
|
||||
{
|
||||
super(NiceMonster).SetZappedBehavior();
|
||||
bUnlit = false;
|
||||
// Handle setting the zed to uncloaked so the zapped overlay works properly
|
||||
if( Level.Netmode != NM_DedicatedServer )
|
||||
{
|
||||
Skins[1] = FinalBlend'MeanZedSkins.stalker_fb';
|
||||
Skins[0] = Combiner'MeanZedSkins.stalker_cmb';
|
||||
|
||||
if (PlayerShadow != none)
|
||||
PlayerShadow.bShadowActive = true;
|
||||
|
||||
bAcceptsProjectors = true;
|
||||
SetOverlayMaterial(Material'KFZED_FX_T.Energy.ZED_overlay_Hit_Shdr', 999, true);
|
||||
}
|
||||
}
|
||||
|
||||
function RangedAttack(Actor A) {
|
||||
if ( bShotAnim || Physics == PHYS_Swimming)
|
||||
return;
|
||||
else if ( CanAttack(A) ) {
|
||||
bShotAnim = true;
|
||||
SetAnimAction('ClawAndMove');
|
||||
//PlaySound(sound'Claw2s', SLOT_none); KFTODO: Replace this
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Copied from the Gorefast code
|
||||
// Overridden to handle playing upper body only attacks when moving
|
||||
simulated event SetAnimAction(name NewAction) {
|
||||
if( NewAction=='' )
|
||||
Return;
|
||||
ExpectingChannel = AttackAndMoveDoAnimAction(NewAction);
|
||||
bWaitForAnim= false;
|
||||
|
||||
if( Level.NetMode!=NM_Client ) {
|
||||
AnimAction = NewAction;
|
||||
bResetAnimAct = True;
|
||||
ResetAnimActTime = Level.TimeSeconds+0.3;
|
||||
}
|
||||
}
|
||||
// Copied from the Gorefast code, updated with the stalker attacks
|
||||
// Handle playing the anim action on the upper body only if we're attacking and moving
|
||||
simulated function int AttackAndMoveDoAnimAction( name AnimName ) {
|
||||
local int meleeAnimIndex;
|
||||
if( AnimName == 'ClawAndMove' ) {
|
||||
meleeAnimIndex = Rand(3);
|
||||
AnimName = meleeAnims[meleeAnimIndex];
|
||||
}
|
||||
if( AnimName=='StalkerSpinAttack' || AnimName=='StalkerAttack1' || AnimName=='JumpAttack') {
|
||||
AnimBlendParams(1, 1.0, 0.0,, FireRootBone);
|
||||
PlayAnim(AnimName,, 0.1, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
return super.DoAnimAction( AnimName );
|
||||
}
|
||||
|
||||
function bool MeleeDamageTarget(int hitdamage, vector pushdir)
|
||||
{
|
||||
local bool result;
|
||||
local float effectStrenght;
|
||||
local NiceHumanPawn targetPawn;
|
||||
|
||||
result = super(NiceMonster).MeleeDamageTarget(hitdamage, pushdir);
|
||||
// if true means we checked ctlr and ctrl.target != none
|
||||
if (result)
|
||||
targetPawn = NiceHumanPawn(Controller.Target);
|
||||
|
||||
if (result && targetPawn != none)
|
||||
{
|
||||
if (targetPawn.ShieldStrength > 100)
|
||||
return result;
|
||||
else if (targetPawn.ShieldStrength <= 0)
|
||||
effectStrenght = 1.0;
|
||||
else
|
||||
effectStrenght = (100 - targetPawn.ShieldStrength) * 0.01;
|
||||
|
||||
MakeBleed(targetPawn, effectStrenght);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
final private function MakeBleed(NiceHumanPawn poorpawn, coerce int effectStrenght)
|
||||
{
|
||||
local Inventory I;
|
||||
local MeanBleedInventory bleedinv;
|
||||
local bool bFoundPoison;
|
||||
|
||||
if (poorpawn.Inventory != none)
|
||||
{
|
||||
for (I = poorpawn.Inventory; I != none; I = I.Inventory)
|
||||
{
|
||||
if (MeanBleedInventory(I) != none)
|
||||
{
|
||||
bleedinv = MeanBleedInventory(I);
|
||||
bFoundPoison = true;
|
||||
bleedinv.stalker = self;
|
||||
bleedinv.bleedLevel = effectStrenght;
|
||||
// reset bleed count
|
||||
bleedinv.maxBleedCount = bleedinv.default.maxBleedCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!bFoundPoison)
|
||||
{
|
||||
I = Controller.Spawn(class<Inventory>(DynamicLoadObject(string(class'MeanBleedInventory'), class'Class')));
|
||||
bleedinv = MeanBleedInventory(I);
|
||||
bleedinv.stalker = self;
|
||||
bleedinv.bleedLevel = effectStrenght;
|
||||
bleedinv.GiveTo(poorpawn);
|
||||
}
|
||||
}
|
||||
|
||||
function RemoveHead()
|
||||
{
|
||||
Super(NiceMonster).RemoveHead();
|
||||
if (!bCrispified)
|
||||
{
|
||||
Skins[1] = FinalBlend'MeanZedSkins.stalker_fb';
|
||||
Skins[0] = Combiner'MeanZedSkins.stalker_cmb';
|
||||
}
|
||||
}
|
||||
simulated function PlayDying(class<DamageType> DamageType, vector HitLoc)
|
||||
{
|
||||
Super(NiceMonster).PlayDying(DamageType,HitLoc);
|
||||
if(bUnlit)
|
||||
bUnlit=!bUnlit;
|
||||
LocalKFHumanPawn = none;
|
||||
if (!bCrispified)
|
||||
{
|
||||
Skins[1] = FinalBlend'MeanZedSkins.stalker_fb';
|
||||
Skins[0] = Combiner'MeanZedSkins.stalker_cmb';
|
||||
}
|
||||
}
|
||||
static simulated function PreCacheMaterials(LevelInfo myLevel)
|
||||
{//should be derived and used.
|
||||
myLevel.AddPrecacheMaterial(Combiner'MeanZedSkins.stalker_cmb');
|
||||
myLevel.AddPrecacheMaterial(Combiner'MeanZedSkins.stalker_env_cmb');
|
||||
myLevel.AddPrecacheMaterial(Texture'MeanZedSkins.stalker_diff');
|
||||
myLevel.AddPrecacheMaterial(Texture'MeanZedSkins.stalker_spec');
|
||||
myLevel.AddPrecacheMaterial(Material'MeanZedSkins.stalker_invisible');
|
||||
myLevel.AddPrecacheMaterial(Combiner'MeanZedSkins.StalkerCloakOpacity_cmb');
|
||||
myLevel.AddPrecacheMaterial(Material'MeanZedSkins.StalkerCloakEnv_rot');
|
||||
myLevel.AddPrecacheMaterial(Material'MeanZedSkins.stalker_opacity_osc');
|
||||
myLevel.AddPrecacheMaterial(Material'KFCharacters.StalkerSkin');
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
MeleeDamage=6
|
||||
MenuName="Mean Stalker"
|
||||
Skins(0)=Shader'MeanZedSkins.stalker_invisible'
|
||||
Skins(1)=Shader'MeanZedSkins.stalker_invisible'
|
||||
}
|
||||
26
kf_sources/NicePack/Classes/Nice9mm.uc
Normal file
26
kf_sources/NicePack/Classes/Nice9mm.uc
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
class Nice9mm extends NiceSingle;
|
||||
static function PreloadAssets(Inventory Inv, optional bool bSkipRefCount){
|
||||
super.PreloadAssets(Inv, bSkipRefCount);
|
||||
// A bit of a temporary hack.
|
||||
// There's currently no nice way to call preload assets function for a grenade, so just always load nails' resources
|
||||
//class'NiceNail'.static.PreloadAssets();
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
DualClass=class'NiceDual9mm'
|
||||
reloadPreEndFrame=0.117000
|
||||
reloadEndFrame=0.617000
|
||||
reloadChargeEndFrame=-1.000000
|
||||
reloadMagStartFrame=0.167000
|
||||
reloadChargeStartFrame=-1.000000
|
||||
HudImage=Texture'KillingFloorHUD.WeaponSelect.single_9mm_unselected'
|
||||
SelectedHudImage=Texture'KillingFloorHUD.WeaponSelect.single_9mm'
|
||||
FireModeClass(0)=class'Nice9mmFire'
|
||||
SelectSound=Sound'KF_9MMSnd.9mm_Select'
|
||||
Description="A 9mm Pistol. What it lacks in stopping power, it compensates for with a quick refire."
|
||||
PickupClass=class'Nice9mmPickup'
|
||||
AttachmentClass=class'Nice9mmAttachment'
|
||||
ItemName="Beretta"
|
||||
Mesh=SkeletalMesh'KF_Weapons_Trip.9mm_Trip'
|
||||
Skins(0)=Combiner'KF_Weapons_Trip_T.Pistols.Ninemm_cmb'
|
||||
}
|
||||
13
kf_sources/NicePack/Classes/Nice9mmAmmo.uc
Normal file
13
kf_sources/NicePack/Classes/Nice9mmAmmo.uc
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
class Nice9mmAmmo extends NiceAmmo;
|
||||
#EXEC OBJ LOAD FILE=InterfaceContent.utx
|
||||
defaultproperties
|
||||
{
|
||||
WeaponPickupClass=class'Nice9mmPickup'
|
||||
AmmoPickupAmount=30
|
||||
MaxAmmo=240
|
||||
InitialAmount=60
|
||||
PickupClass=Class'KFMod.SingleAmmoPickup'
|
||||
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
|
||||
IconCoords=(X1=413,Y1=82,X2=457,Y2=125)
|
||||
ItemName="9mm bullets"
|
||||
}
|
||||
9
kf_sources/NicePack/Classes/Nice9mmAmmoPickup.uc
Normal file
9
kf_sources/NicePack/Classes/Nice9mmAmmoPickup.uc
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
class Nice9mmAmmoPickup extends NiceAmmoPickup;
|
||||
defaultproperties
|
||||
{
|
||||
AmmoAmount=30
|
||||
InventoryType=class'Nice9mmAmmo'
|
||||
RespawnTime=0.000000
|
||||
PickupMessage="Rounds (9mm)"
|
||||
StaticMesh=StaticMesh'KillingFloorStatics.DualiesAmmo'
|
||||
}
|
||||
5
kf_sources/NicePack/Classes/Nice9mmAttachment.uc
Normal file
5
kf_sources/NicePack/Classes/Nice9mmAttachment.uc
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class Nice9mmAttachment extends NiceSingleAttachment;
|
||||
defaultproperties
|
||||
{
|
||||
Mesh=SkeletalMesh'KF_Weapons3rd_Trip.Single9mm_3rd'
|
||||
}
|
||||
12
kf_sources/NicePack/Classes/Nice9mmFire.uc
Normal file
12
kf_sources/NicePack/Classes/Nice9mmFire.uc
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
class Nice9mmFire extends NiceSingleFire;
|
||||
defaultproperties
|
||||
{
|
||||
ProjectileSpeed=21300.000000
|
||||
maxVerticalRecoilAngle=75
|
||||
maxHorizontalRecoilAngle=35
|
||||
StereoFireSound=SoundGroup'KF_9MMSnd.9mm_FireST'
|
||||
DamageType=class'NiceDamType9mm'
|
||||
FireSound=SoundGroup'KF_9MMSnd.9mm_Fire'
|
||||
NoAmmoSound=Sound'KF_9MMSnd.9mm_DryFire'
|
||||
AmmoClass=class'Nice9mmAmmo'
|
||||
}
|
||||
10
kf_sources/NicePack/Classes/Nice9mmPickup.uc
Normal file
10
kf_sources/NicePack/Classes/Nice9mmPickup.uc
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
class Nice9mmPickup extends NiceSinglePickup;
|
||||
defaultproperties
|
||||
{
|
||||
bBackupWeapon=True
|
||||
cost=100
|
||||
Description="A 9mm Pistol. What it lacks in stopping power, it compensates for with a quick refire."
|
||||
ItemName="Beretta"
|
||||
ItemShortName="Beretta"
|
||||
InventoryType=class'Nice9mm'
|
||||
}
|
||||
47
kf_sources/NicePack/Classes/Nice9mmPlus.uc
Normal file
47
kf_sources/NicePack/Classes/Nice9mmPlus.uc
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
class Nice9mmPlus extends NiceSingle;
|
||||
simulated function AltFire(float F){
|
||||
if(bIsDual)
|
||||
super.AltFire(F);
|
||||
else
|
||||
ToggleLaser();
|
||||
}
|
||||
simulated function SecondDoToggle(){
|
||||
ToggleLaser();
|
||||
}
|
||||
simulated function ToggleLaser(){
|
||||
if(!Instigator.IsLocallyControlled())
|
||||
return;
|
||||
// Will redo this bit later, but so far it'll have to do
|
||||
if(LaserType == 0)
|
||||
LaserType = 1;
|
||||
else
|
||||
LaserType = 0;
|
||||
ApplyLaserState();
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
DualClass=class'NiceDual9mmPlus'
|
||||
bUseFlashlightToToggle=True
|
||||
reloadPreEndFrame=0.117000
|
||||
reloadEndFrame=0.617000
|
||||
reloadChargeEndFrame=-1.000000
|
||||
reloadMagStartFrame=0.167000
|
||||
reloadChargeStartFrame=-1.000000
|
||||
bTorchEnabled=True
|
||||
SleeveNum=0
|
||||
TraderInfoTexture=Texture'NicePackT.NinePP.HUD_Single_Trader'
|
||||
MeshRef="NicePackA.NinePP.Single_1P"
|
||||
SkinRefs(1)="ScrnWeaponPack_T.MedicPistol.Slide_cmb"
|
||||
SkinRefs(2)="ScrnWeaponPack_T.MedicPistol.frame_cmb"
|
||||
SkinRefs(3)="ScrnWeaponPack_T.MedicPistol.Slide_cmb"
|
||||
SkinRefs(4)="ScrnWeaponPack_T.MedicPistol.Slide_cmb"
|
||||
SelectSoundRef="KF_9MMSnd.9mm_Select"
|
||||
HudImageRef="NicePackT.NinePP.HUD_Single_UnSelected"
|
||||
SelectedHudImageRef="NicePackT.NinePP.HUD_Single_Selected"
|
||||
FireModeClass(0)=class'Nice9mmPlusFire'
|
||||
Description="A 9mm handgun, with a functional laser sight and flashlight. The barrel has been replaced with one that can chamber hotter ammunition loads, meaning faster bullets, meaning more damage!"
|
||||
GroupOffset=3
|
||||
PickupClass=class'Nice9mmPlusPickup'
|
||||
AttachmentClass=class'Nice9mmPlusAttachment'
|
||||
ItemName="Beretta"
|
||||
}
|
||||
12
kf_sources/NicePack/Classes/Nice9mmPlusAmmo.uc
Normal file
12
kf_sources/NicePack/Classes/Nice9mmPlusAmmo.uc
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
class Nice9mmPlusAmmo extends NiceAmmo;
|
||||
defaultproperties
|
||||
{
|
||||
WeaponPickupClass=class'Nice9mmPlusPickup'
|
||||
AmmoPickupAmount=15
|
||||
MaxAmmo=150
|
||||
InitialAmount=60
|
||||
PickupClass=class'Nice9mmPlusAmmoPickup'
|
||||
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
|
||||
IconCoords=(X1=413,Y1=82,X2=457,Y2=125)
|
||||
ItemName="9mm +P+ bullets"
|
||||
}
|
||||
9
kf_sources/NicePack/Classes/Nice9mmPlusAmmoPickup.uc
Normal file
9
kf_sources/NicePack/Classes/Nice9mmPlusAmmoPickup.uc
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
class Nice9mmPlusAmmoPickup extends NiceAmmoPickup;
|
||||
defaultproperties
|
||||
{
|
||||
AmmoAmount=15
|
||||
InventoryType=class'Nice9mmPlusAmmo'
|
||||
RespawnTime=0.000000
|
||||
PickupMessage="Rounds (9mm +P+)"
|
||||
StaticMesh=StaticMesh'KillingFloorStatics.DualiesAmmo'
|
||||
}
|
||||
5
kf_sources/NicePack/Classes/Nice9mmPlusAttachment.uc
Normal file
5
kf_sources/NicePack/Classes/Nice9mmPlusAttachment.uc
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class Nice9mmPlusAttachment extends NiceSingleAttachment;
|
||||
defaultproperties
|
||||
{
|
||||
MeshRef="NicePackA.NinePP.Single_3P"
|
||||
}
|
||||
13
kf_sources/NicePack/Classes/Nice9mmPlusFire.uc
Normal file
13
kf_sources/NicePack/Classes/Nice9mmPlusFire.uc
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
class Nice9mmPlusFire extends NiceSingleFire;
|
||||
defaultproperties
|
||||
{
|
||||
ProjectileSpeed=21300.000000
|
||||
maxVerticalRecoilAngle=0
|
||||
maxHorizontalRecoilAngle=0
|
||||
FireSoundRef="NicePackSnd.NinePP.Fire1"
|
||||
StereoFireSoundRef="NicePackSnd.NinePP.Fire1"
|
||||
NoAmmoSoundRef="KF_9MMSnd.9mm_DryFire"
|
||||
DamageType=class'NiceDamType9mmPlus'
|
||||
FireRate=0.250000
|
||||
AmmoClass=class'Nice9mmPlusAmmo'
|
||||
}
|
||||
15
kf_sources/NicePack/Classes/Nice9mmPlusPickup.uc
Normal file
15
kf_sources/NicePack/Classes/Nice9mmPlusPickup.uc
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
class Nice9mmPlusPickup extends NiceSinglePickup;
|
||||
defaultproperties
|
||||
{
|
||||
bBackupWeapon=True
|
||||
cost=100
|
||||
AmmoCost=5
|
||||
BuyClipSize=15
|
||||
Description="A 9mm handgun, with a functional laser sight and flashlight. The barrel has been replaced with one that can chamber hotter ammunition loads, meaning faster bullets, meaning more damage!"
|
||||
ItemName="Beretta"
|
||||
ItemShortName="9mm"
|
||||
InventoryType=class'Nice9mmPlus'
|
||||
PickupMessage="You got the 9mm!"
|
||||
StaticMesh=StaticMesh'NicePackSM.NinePP.Pickup'
|
||||
DrawScale=0.100000
|
||||
}
|
||||
12
kf_sources/NicePack/Classes/NiceAA12Ammo.uc
Normal file
12
kf_sources/NicePack/Classes/NiceAA12Ammo.uc
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
class NiceAA12Ammo extends NiceAmmo;
|
||||
#EXEC OBJ LOAD FILE=KillingFloorHUD.utx
|
||||
defaultproperties
|
||||
{
|
||||
WeaponPickupClass=class'NiceAA12Pickup'
|
||||
AmmoPickupAmount=20
|
||||
MaxAmmo=100
|
||||
InitialAmount=25
|
||||
PickupClass=class'NiceAA12AmmoPickup'
|
||||
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
|
||||
IconCoords=(X1=451,Y1=445,X2=510,Y2=500)
|
||||
}
|
||||
8
kf_sources/NicePack/Classes/NiceAA12AmmoPickup.uc
Normal file
8
kf_sources/NicePack/Classes/NiceAA12AmmoPickup.uc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
class NiceAA12AmmoPickup extends NiceAmmoPickup;
|
||||
defaultproperties
|
||||
{
|
||||
AmmoAmount=20
|
||||
InventoryType=class'NiceAA12Ammo'
|
||||
PickupMessage="12-Gauge Drum"
|
||||
StaticMesh=None
|
||||
}
|
||||
51
kf_sources/NicePack/Classes/NiceAA12Attachment.uc
Normal file
51
kf_sources/NicePack/Classes/NiceAA12Attachment.uc
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
class NiceAA12Attachment extends NiceAttachment;
|
||||
defaultproperties
|
||||
{
|
||||
mMuzFlashClass=Class'ROEffects.MuzzleFlash3rdKar'
|
||||
mShellCaseEmitterClass=Class'KFMod.KFShotgunShellSpewer'
|
||||
MovementAnims(0)="JogF_AA12"
|
||||
MovementAnims(1)="JogB_AA12"
|
||||
MovementAnims(2)="JogL_AA12"
|
||||
MovementAnims(3)="JogR_AA12"
|
||||
TurnLeftAnim="TurnL_AA12"
|
||||
TurnRightAnim="TurnR_AA12"
|
||||
CrouchAnims(0)="CHWalkF_AA12"
|
||||
CrouchAnims(1)="CHWalkB_AA12"
|
||||
CrouchAnims(2)="CHWalkL_AA12"
|
||||
CrouchAnims(3)="CHWalkR_AA12"
|
||||
WalkAnims(0)="WalkF_AA12"
|
||||
WalkAnims(1)="WalkB_AA12"
|
||||
WalkAnims(2)="WalkL_AA12"
|
||||
WalkAnims(3)="WalkR_AA12"
|
||||
CrouchTurnRightAnim="CH_TurnR_AA12"
|
||||
CrouchTurnLeftAnim="CH_TurnL_AA12"
|
||||
IdleCrouchAnim="CHIdle_AA12"
|
||||
IdleWeaponAnim="Idle_AA12"
|
||||
IdleRestAnim="Idle_AA12"
|
||||
IdleChatAnim="Idle_AA12"
|
||||
IdleHeavyAnim="Idle_AA12"
|
||||
IdleRifleAnim="Idle_AA12"
|
||||
FireAnims(0)="Fire_AA12"
|
||||
FireAnims(1)="Fire_AA12"
|
||||
FireAnims(2)="Fire_AA12"
|
||||
FireAnims(3)="Fire_AA12"
|
||||
FireAltAnims(0)="Fire_AA12"
|
||||
FireAltAnims(1)="Fire_AA12"
|
||||
FireAltAnims(2)="Fire_AA12"
|
||||
FireAltAnims(3)="Fire_AA12"
|
||||
FireCrouchAnims(0)="CHFire_AA12"
|
||||
FireCrouchAnims(1)="CHFire_AA12"
|
||||
FireCrouchAnims(2)="CHFire_AA12"
|
||||
FireCrouchAnims(3)="CHFire_AA12"
|
||||
FireCrouchAltAnims(0)="CHFire_AA12"
|
||||
FireCrouchAltAnims(1)="CHFire_AA12"
|
||||
FireCrouchAltAnims(2)="CHFire_AA12"
|
||||
FireCrouchAltAnims(3)="CHFire_AA12"
|
||||
HitAnims(0)="HitF_AA12"
|
||||
HitAnims(1)="HitB_AA12"
|
||||
HitAnims(2)="HitL_AA12"
|
||||
HitAnims(3)="HitR_AA12"
|
||||
PostFireBlendStandAnim="Blend_AA12"
|
||||
PostFireBlendCrouchAnim="CHBlend_AA12"
|
||||
MeshRef="KF_Weapons3rd2_Trip.AA12_3rd"
|
||||
}
|
||||
57
kf_sources/NicePack/Classes/NiceAA12AutoShotgun.uc
Normal file
57
kf_sources/NicePack/Classes/NiceAA12AutoShotgun.uc
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
class NiceAA12AutoShotgun extends NiceWeapon;
|
||||
|
||||
// Use alt fire to switch fire modes
|
||||
simulated function AltFire(float F){
|
||||
DoToggle();
|
||||
}
|
||||
|
||||
exec function SwitchModes(){
|
||||
DoToggle();
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
reloadPreEndFrame=0.473000
|
||||
reloadEndFrame=0.828000
|
||||
reloadChargeEndFrame=-1.000000
|
||||
reloadMagStartFrame=0.591000
|
||||
reloadChargeStartFrame=-1.000000
|
||||
MagCapacity=20
|
||||
Weight=6.000000
|
||||
ReloadRate=3.133000
|
||||
ReloadAnim="Reload"
|
||||
ReloadAnimRate=1.000000
|
||||
WeaponReloadAnim="Reload_AA12"
|
||||
bHasAimingMode=True
|
||||
IdleAimAnim="Idle_Iron"
|
||||
StandardDisplayFOV=65.000000
|
||||
TraderInfoTexture=Texture'KillingFloor2HUD.Trader_Weapon_Icons.Trader_AA12'
|
||||
bIsTier3Weapon=True
|
||||
MeshRef="KF_Weapons2_Trip.AA12_Trip"
|
||||
SkinRefs(0)="KF_Weapons2_Trip_T.Special.AA12_cmb"
|
||||
SelectSoundRef="KF_AA12Snd.AA12_Select"
|
||||
HudImageRef="KillingFloor2HUD.WeaponSelect.AA12_unselected"
|
||||
SelectedHudImageRef="KillingFloor2HUD.WeaponSelect.AA12"
|
||||
PlayerIronSightFOV=80.000000
|
||||
ZoomedDisplayFOV=45.000000
|
||||
FireModeClass(0)=class'NiceAA12Fire'
|
||||
FireModeClass(1)=Class'KFMod.NoFire'
|
||||
PutDownAnim="PutDown"
|
||||
SelectForce="SwitchToAssaultRifle"
|
||||
AIRating=0.550000
|
||||
CurrentRating=0.550000
|
||||
bShowChargingBar=True
|
||||
Description="An advanced fully automatic shotgun."
|
||||
EffectOffset=(X=100.000000,Y=25.000000,Z=-10.000000)
|
||||
DisplayFOV=65.000000
|
||||
Priority=200
|
||||
InventoryGroup=4
|
||||
GroupOffset=10
|
||||
PickupClass=class'NiceAA12Pickup'
|
||||
PlayerViewOffset=(X=25.000000,Y=20.000000,Z=-2.000000)
|
||||
BobDamping=6.000000
|
||||
AttachmentClass=class'NiceAA12Attachment'
|
||||
IconCoords=(X1=245,Y1=39,X2=329,Y2=79)
|
||||
ItemName="AA12 Shotgun"
|
||||
TransientSoundVolume=1.250000
|
||||
}
|
||||
26
kf_sources/NicePack/Classes/NiceAA12Fire.uc
Normal file
26
kf_sources/NicePack/Classes/NiceAA12Fire.uc
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
class NiceAA12Fire extends NiceShotgunFire;
|
||||
defaultproperties
|
||||
{
|
||||
ProjPerFire=5
|
||||
KickMomentum=(X=-35.000000,Z=5.000000)
|
||||
maxVerticalRecoilAngle=1000
|
||||
maxHorizontalRecoilAngle=500
|
||||
ShellEjectClass=Class'ROEffects.KFShellEjectShotty'
|
||||
ShellEjectBoneName="Shell_eject"
|
||||
FireSoundRef="KF_AA12Snd.AA12_Fire"
|
||||
StereoFireSoundRef="KF_AA12Snd.AA12_FireST"
|
||||
NoAmmoSoundRef="KF_AA12Snd.AA12_DryFire"
|
||||
DamageType=class'NiceDamTypeAA12Shotgun'
|
||||
DamageMax=48
|
||||
Momentum=60000.000000
|
||||
bWaitForRelease=False
|
||||
FireAnimRate=1.000000
|
||||
FireRate=0.200000
|
||||
AmmoClass=class'NiceAA12Ammo'
|
||||
ShakeRotMag=(Z=250.000000)
|
||||
ShakeRotTime=3.000000
|
||||
ShakeOffsetMag=(Z=6.000000)
|
||||
ShakeOffsetTime=1.250000
|
||||
BotRefireRate=0.250000
|
||||
Spread=1125.000000
|
||||
}
|
||||
24
kf_sources/NicePack/Classes/NiceAA12Pickup.uc
Normal file
24
kf_sources/NicePack/Classes/NiceAA12Pickup.uc
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
class NiceAA12Pickup extends NiceWeaponPickup;
|
||||
defaultproperties
|
||||
{
|
||||
cost=1250
|
||||
AmmoCost=50
|
||||
BuyClipSize=20
|
||||
PowerValue=85
|
||||
SpeedValue=65
|
||||
RangeValue=20
|
||||
Description="An advanced fully automatic shotgun."
|
||||
ItemName="AA12 Shotgun"
|
||||
ItemShortName="AA12 Shotgun"
|
||||
AmmoItemName="12-gauge drum"
|
||||
CorrespondingPerkIndex=1
|
||||
EquipmentCategoryID=3
|
||||
VariantClasses(0)=Class'KFMod.GoldenAA12Pickup'
|
||||
InventoryType=class'NiceAA12AutoShotgun'
|
||||
PickupMessage="You got the AA12 auto shotgun."
|
||||
PickupSound=Sound'KF_AA12Snd.AA12_Pickup'
|
||||
PickupForce="AssaultRiflePickup"
|
||||
StaticMesh=StaticMesh'KF_pickups2_Trip.Shotguns.AA12_Pickup'
|
||||
CollisionRadius=35.000000
|
||||
CollisionHeight=5.000000
|
||||
}
|
||||
13
kf_sources/NicePack/Classes/NiceAK12Ammo.uc
Normal file
13
kf_sources/NicePack/Classes/NiceAK12Ammo.uc
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
class NiceAK12Ammo extends NiceAmmo;
|
||||
#EXEC OBJ LOAD FILE=KillingFloorHUD.utx
|
||||
defaultproperties
|
||||
{
|
||||
WeaponPickupClass=class'NiceAK12Pickup'
|
||||
AmmoPickupAmount=30
|
||||
MaxAmmo=270
|
||||
InitialAmount=60
|
||||
PickupClass=class'NiceAK12AmmoPickup'
|
||||
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
|
||||
IconCoords=(X1=336,Y1=82,X2=382,Y2=125)
|
||||
ItemName="5.45x39mm"
|
||||
}
|
||||
8
kf_sources/NicePack/Classes/NiceAK12AmmoPickup.uc
Normal file
8
kf_sources/NicePack/Classes/NiceAK12AmmoPickup.uc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
class NiceAK12AmmoPickup extends NiceAmmoPickup;
|
||||
defaultproperties
|
||||
{
|
||||
AmmoAmount=30
|
||||
InventoryType=class'NiceAK12Ammo'
|
||||
PickupMessage="Rounds 5.45x39mm"
|
||||
StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo'
|
||||
}
|
||||
62
kf_sources/NicePack/Classes/NiceAK12AssaultRifle.uc
Normal file
62
kf_sources/NicePack/Classes/NiceAK12AssaultRifle.uc
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
class NiceAK12AssaultRifle extends NiceAssaultRifle;
|
||||
defaultproperties
|
||||
{
|
||||
bSemiAutoFireEnabled=False
|
||||
bBurstFireEnabled=True
|
||||
reloadPreEndFrame=0.158000
|
||||
reloadEndFrame=0.521000
|
||||
reloadChargeEndFrame=0.726000
|
||||
reloadMagStartFrame=0.363000
|
||||
reloadChargeStartFrame=0.726000
|
||||
MagazineBone="Bone_Magazine"
|
||||
MagCapacity=40
|
||||
ReloadRate=3.000000
|
||||
ReloadAnim="Reload"
|
||||
ReloadAnimRate=1.000000
|
||||
WeaponReloadAnim="Reload_AK47"
|
||||
Weight=6.000000
|
||||
bHasAimingMode=True
|
||||
IdleAimAnim="Idle_Iron"
|
||||
StandardDisplayFOV=55.000000
|
||||
SleeveNum=8
|
||||
TraderInfoTexture=Texture'ScrnWeaponPack_T.AK12.AK12_trader'
|
||||
bIsTier3Weapon=True
|
||||
MeshRef="ScrnWeaponPack_A.AK12_mesh"
|
||||
SkinRefs(0)="ScrnWeaponPack_T.AK12.AK12_tex_1_cmb"
|
||||
SkinRefs(1)="ScrnWeaponPack_T.AK12.AK12_tex_2_cmb"
|
||||
SkinRefs(2)="ScrnWeaponPack_T.AK12.AK12_tex_3_cmb"
|
||||
SkinRefs(3)="ScrnWeaponPack_T.AK12.AK12_tex_4_cmb"
|
||||
SkinRefs(4)="ScrnWeaponPack_T.AK12.AK12_tex_5_cmb"
|
||||
SkinRefs(5)="ScrnWeaponPack_T.AK12.AK12_tex_6_cmb"
|
||||
SkinRefs(6)="ScrnWeaponPack_T.AK12.AK12_tex_7_cmb"
|
||||
SkinRefs(7)="ScrnWeaponPack_T.AK12.AK12_aimpoint_sh"
|
||||
SkinRefs(8)="KF_Weapons_Trip_T.hands.hands_1stP_military_cmb"
|
||||
SelectSoundRef="ScrnWeaponPack_SND.AK12.AK12_select"
|
||||
HudImageRef="ScrnWeaponPack_T.AK12.AK12_Unselect"
|
||||
SelectedHudImageRef="ScrnWeaponPack_T.AK12.AK12_select"
|
||||
PlayerIronSightFOV=65.000000
|
||||
ZoomedDisplayFOV=20.000000
|
||||
FireModeClass(0)=class'NiceAK12Fire'
|
||||
FireModeClass(1)=Class'KFMod.NoFire'
|
||||
PutDownAnim="PutDown"
|
||||
SelectAnimRate=1.300000
|
||||
SelectForce="SwitchToAssaultRifle"
|
||||
AIRating=0.550000
|
||||
CurrentRating=0.550000
|
||||
bShowChargingBar=True
|
||||
Description="The Kalashnikov AK-12 (formerly AK-200) is the newest derivative of the Soviet/Russian AK-47 series of assault rifles and was proposed for possible general issue to the Russian Army. This version uses the 5.45x39mm ammo (the same as AK-74)"
|
||||
EffectOffset=(X=100.000000,Y=25.000000,Z=-10.000000)
|
||||
DisplayFOV=55.000000
|
||||
Priority=145
|
||||
CustomCrosshair=11
|
||||
CustomCrossHairTextureName="Crosshairs.HUD.Crosshair_Cross5"
|
||||
InventoryGroup=4
|
||||
GroupOffset=7
|
||||
PickupClass=class'NiceAK12Pickup'
|
||||
PlayerViewOffset=(X=-0.500000,Y=20.000000,Z=-3.000000)
|
||||
BobDamping=6.000000
|
||||
AttachmentClass=class'NiceAK12Attachment'
|
||||
IconCoords=(X1=245,Y1=39,X2=329,Y2=79)
|
||||
ItemName="AK12"
|
||||
TransientSoundVolume=1.250000
|
||||
}
|
||||
57
kf_sources/NicePack/Classes/NiceAK12Attachment.uc
Normal file
57
kf_sources/NicePack/Classes/NiceAK12Attachment.uc
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
class NiceAK12Attachment extends NiceAttachment;
|
||||
simulated function WeaponLight();
|
||||
defaultproperties
|
||||
{
|
||||
bSpawnLight=False
|
||||
mMuzFlashClass=Class'ScrnWeaponPack.MuzzleFlashAK12AR'
|
||||
mTracerClass=Class'KFMod.KFNewTracer'
|
||||
mShellCaseEmitterClass=Class'KFMod.KFShellSpewer'
|
||||
MovementAnims(0)="JogF_AK47"
|
||||
MovementAnims(1)="JogB_AK47"
|
||||
MovementAnims(2)="JogL_AK47"
|
||||
MovementAnims(3)="JogR_AK47"
|
||||
TurnLeftAnim="TurnL_AK47"
|
||||
TurnRightAnim="TurnR_AK47"
|
||||
CrouchAnims(0)="CHWalkF_AK47"
|
||||
CrouchAnims(1)="CHWalkB_AK47"
|
||||
CrouchAnims(2)="CHWalkL_AK47"
|
||||
CrouchAnims(3)="CHWalkR_AK47"
|
||||
WalkAnims(0)="WalkF_AK47"
|
||||
WalkAnims(1)="WalkB_AK47"
|
||||
WalkAnims(2)="WalkL_AK47"
|
||||
WalkAnims(3)="WalkR_AK47"
|
||||
CrouchTurnRightAnim="CH_TurnR_AK47"
|
||||
CrouchTurnLeftAnim="CH_TurnL_AK47"
|
||||
IdleCrouchAnim="CHIdle_AK47"
|
||||
IdleWeaponAnim="Idle_AK47"
|
||||
IdleRestAnim="Idle_AK47"
|
||||
IdleChatAnim="Idle_AK47"
|
||||
IdleHeavyAnim="Idle_AK47"
|
||||
IdleRifleAnim="Idle_AK47"
|
||||
FireAnims(0)="Fire_AK47"
|
||||
FireAnims(1)="Fire_AK47"
|
||||
FireAnims(2)="Fire_AK47"
|
||||
FireAnims(3)="Fire_AK47"
|
||||
FireAltAnims(0)="IS_Fire_AK47"
|
||||
FireAltAnims(1)="IS_Fire_AK47"
|
||||
FireAltAnims(2)="IS_Fire_AK47"
|
||||
FireAltAnims(3)="IS_Fire_AK47"
|
||||
FireCrouchAnims(0)="CHFire_AK47"
|
||||
FireCrouchAnims(1)="CHFire_AK47"
|
||||
FireCrouchAnims(2)="CHFire_AK47"
|
||||
FireCrouchAnims(3)="CHFire_AK47"
|
||||
FireCrouchAltAnims(0)="CHFire_AK47"
|
||||
FireCrouchAltAnims(1)="CHFire_AK47"
|
||||
FireCrouchAltAnims(2)="CHFire_AK47"
|
||||
FireCrouchAltAnims(3)="CHFire_AK47"
|
||||
HitAnims(0)="HitF_AK47"
|
||||
HitAnims(1)="HitB_AK47"
|
||||
HitAnims(2)="HitL_AK47"
|
||||
HitAnims(3)="HitR_AK47"
|
||||
PostFireBlendStandAnim="Blend_AK47"
|
||||
PostFireBlendCrouchAnim="CHBlend_AK47"
|
||||
MeshRef="ScrnWeaponPack_A.AK12_3rd"
|
||||
bHeavy=True
|
||||
SplashEffect=Class'ROEffects.BulletSplashEmitter'
|
||||
CullDistance=5000.000000
|
||||
}
|
||||
37
kf_sources/NicePack/Classes/NiceAK12Fire.uc
Normal file
37
kf_sources/NicePack/Classes/NiceAK12Fire.uc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
class NiceAK12Fire extends NiceFire;
|
||||
defaultproperties
|
||||
{
|
||||
MaxBurstLength=4
|
||||
zedTimeFireSpeedUp=1.500000
|
||||
ProjectileSpeed=44000.000000
|
||||
FireAimedAnim="Fire_Iron"
|
||||
RecoilRate=0.040000
|
||||
maxVerticalRecoilAngle=160
|
||||
maxHorizontalRecoilAngle=80
|
||||
ShellEjectClass=Class'ScrnWeaponPack.KFShellEjectAK12AR'
|
||||
ShellEjectBoneName="Shell_eject"
|
||||
bAccuracyBonusForSemiAuto=True
|
||||
bRandomPitchFireSound=False
|
||||
FireSoundRef="ScrnWeaponPack_SND.AK12.AK12_shot"
|
||||
StereoFireSoundRef="ScrnWeaponPack_SND.AK12.AK12_shot"
|
||||
NoAmmoSoundRef="ScrnWeaponPack_SND.AK12.AK12_empty"
|
||||
DamageType=class'NiceDamTypeAK12AssaultRifle'
|
||||
DamageMax=68
|
||||
Momentum=18500.000000
|
||||
bPawnRapidFireAnim=True
|
||||
TransientSoundVolume=3.800000
|
||||
FireLoopAnim="Fire"
|
||||
TweenTime=0.025000
|
||||
FireForce="AssaultRifleFire"
|
||||
FireRate=0.095000
|
||||
AmmoClass=class'NiceAK12Ammo'
|
||||
ShakeRotMag=(X=50.000000,Y=50.000000,Z=350.000000)
|
||||
ShakeRotRate=(X=5000.000000,Y=5000.000000,Z=5000.000000)
|
||||
ShakeRotTime=0.750000
|
||||
ShakeOffsetMag=(X=6.000000,Y=3.000000,Z=7.500000)
|
||||
ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000)
|
||||
ShakeOffsetTime=1.250000
|
||||
BotRefireRate=0.990000
|
||||
FlashEmitterClass=Class'ScrnWeaponPack.MuzzleFlashAK12AR'
|
||||
aimerror=42.000000
|
||||
}
|
||||
26
kf_sources/NicePack/Classes/NiceAK12Pickup.uc
Normal file
26
kf_sources/NicePack/Classes/NiceAK12Pickup.uc
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
class NiceAK12Pickup extends NiceWeaponPickup;
|
||||
defaultproperties
|
||||
{
|
||||
Weight=6.000000
|
||||
cost=750
|
||||
AmmoCost=25
|
||||
BuyClipSize=40
|
||||
PowerValue=55
|
||||
SpeedValue=80
|
||||
RangeValue=30
|
||||
Description="The Kalashnikov AK-12 (formerly AK-200) is the newest derivative of the Soviet/Russian AK-47 series of assault rifles and was proposed for possible general issue to the Russian Army. This version uses the 5.45x39mm ammo (the same as AK-74)"
|
||||
ItemName="AK12"
|
||||
ItemShortName="AK12"
|
||||
AmmoItemName="5.45x39mm"
|
||||
AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo'
|
||||
CorrespondingPerkIndex=3
|
||||
EquipmentCategoryID=2
|
||||
InventoryType=class'NiceAK12AssaultRifle'
|
||||
PickupMessage="You got the AK-12"
|
||||
PickupSound=Sound'ScrnWeaponPack_SND.AK12.AK12_select'
|
||||
PickupForce="AssaultRiflePickup"
|
||||
StaticMesh=StaticMesh'ScrnWeaponPack_SM.AK12_st'
|
||||
DrawScale=1.100000
|
||||
CollisionRadius=25.000000
|
||||
CollisionHeight=5.000000
|
||||
}
|
||||
13
kf_sources/NicePack/Classes/NiceAK47Ammo.uc
Normal file
13
kf_sources/NicePack/Classes/NiceAK47Ammo.uc
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
class NiceAK47Ammo extends NiceAmmo;
|
||||
#EXEC OBJ LOAD FILE=KillingFloorHUD.utx
|
||||
defaultproperties
|
||||
{
|
||||
WeaponPickupClass=class'NiceAK47Pickup'
|
||||
AmmoPickupAmount=30
|
||||
MaxAmmo=240
|
||||
InitialAmount=90
|
||||
PickupClass=class'NiceAK47AmmoPickup'
|
||||
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
|
||||
IconCoords=(X1=336,Y1=82,X2=382,Y2=125)
|
||||
ItemName="AK47 bullets"
|
||||
}
|
||||
8
kf_sources/NicePack/Classes/NiceAK47AmmoPickup.uc
Normal file
8
kf_sources/NicePack/Classes/NiceAK47AmmoPickup.uc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
class NiceAK47AmmoPickup extends NiceAmmoPickup;
|
||||
defaultproperties
|
||||
{
|
||||
AmmoAmount=30
|
||||
InventoryType=class'NiceAK47Ammo'
|
||||
PickupMessage="Rounds 7.62mm"
|
||||
StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo'
|
||||
}
|
||||
55
kf_sources/NicePack/Classes/NiceAK47AssaultRifle.uc
Normal file
55
kf_sources/NicePack/Classes/NiceAK47AssaultRifle.uc
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
class NiceAK47AssaultRifle extends NiceAssaultRifle;
|
||||
#exec OBJ LOAD FILE=KillingFloorWeapons.utx
|
||||
#exec OBJ LOAD FILE=KillingFloorHUD.utx
|
||||
#exec OBJ LOAD FILE=Inf_Weapons_Foley.uax
|
||||
defaultproperties
|
||||
{
|
||||
bSemiAutoFireEnabled=False
|
||||
bBurstFireEnabled=True
|
||||
reloadPreEndFrame=0.167000
|
||||
reloadEndFrame=0.578000
|
||||
reloadChargeEndFrame=0.800000
|
||||
reloadMagStartFrame=0.433000
|
||||
reloadChargeStartFrame=0.711000
|
||||
MagazineBone="MagazineAK"
|
||||
MagCapacity=30
|
||||
ReloadRate=3.000000
|
||||
ReloadAnim="Reload"
|
||||
ReloadAnimRate=1.000000
|
||||
WeaponReloadAnim="Reload_AK47"
|
||||
Weight=6.000000
|
||||
bHasAimingMode=True
|
||||
IdleAimAnim="Idle_Iron"
|
||||
StandardDisplayFOV=60.000000
|
||||
TraderInfoTexture=Texture'KillingFloor2HUD.Trader_Weapon_Icons.Trader_AK_47'
|
||||
bIsTier2Weapon=True
|
||||
MeshRef="KF_Weapons2_Trip.AK47_Trip"
|
||||
SkinRefs(0)="KF_Weapons2_Trip_T.Rifles.AK47_cmb"
|
||||
SelectSoundRef="KF_AK47Snd.AK47_Select"
|
||||
HudImageRef="KillingFloor2HUD.WeaponSelect.Ak_47_unselected"
|
||||
SelectedHudImageRef="KillingFloor2HUD.WeaponSelect.Ak_47"
|
||||
PlayerIronSightFOV=65.000000
|
||||
ZoomedDisplayFOV=32.000000
|
||||
FireModeClass(0)=class'NiceAK47Fire'
|
||||
FireModeClass(1)=Class'KFMod.NoFire'
|
||||
PutDownAnim="PutDown"
|
||||
SelectForce="SwitchToAssaultRifle"
|
||||
AIRating=0.550000
|
||||
CurrentRating=0.550000
|
||||
bShowChargingBar=True
|
||||
Description="A classic Russian assault rifle. Can be fired in semi or full auto with nice knock down power but not great accuracy."
|
||||
EffectOffset=(X=100.000000,Y=25.000000,Z=-10.000000)
|
||||
DisplayFOV=60.000000
|
||||
Priority=95
|
||||
CustomCrosshair=11
|
||||
CustomCrossHairTextureName="Crosshairs.HUD.Crosshair_Cross5"
|
||||
InventoryGroup=3
|
||||
GroupOffset=7
|
||||
PickupClass=class'NiceAK47Pickup'
|
||||
PlayerViewOffset=(X=18.000000,Y=22.000000,Z=-6.000000)
|
||||
BobDamping=6.000000
|
||||
AttachmentClass=class'NiceAK47Attachment'
|
||||
IconCoords=(X1=245,Y1=39,X2=329,Y2=79)
|
||||
ItemName="AK47"
|
||||
TransientSoundVolume=1.250000
|
||||
}
|
||||
56
kf_sources/NicePack/Classes/NiceAK47Attachment.uc
Normal file
56
kf_sources/NicePack/Classes/NiceAK47Attachment.uc
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
class NiceAK47Attachment extends NiceAttachment;
|
||||
defaultproperties
|
||||
{
|
||||
mMuzFlashClass=Class'ROEffects.MuzzleFlash3rdMP'
|
||||
mTracerClass=Class'KFMod.KFNewTracer'
|
||||
mShellCaseEmitterClass=Class'KFMod.KFShellSpewer'
|
||||
MovementAnims(0)="JogF_AK47"
|
||||
MovementAnims(1)="JogB_AK47"
|
||||
MovementAnims(2)="JogL_AK47"
|
||||
MovementAnims(3)="JogR_AK47"
|
||||
TurnLeftAnim="TurnL_AK47"
|
||||
TurnRightAnim="TurnR_AK47"
|
||||
CrouchAnims(0)="CHWalkF_AK47"
|
||||
CrouchAnims(1)="CHWalkB_AK47"
|
||||
CrouchAnims(2)="CHWalkL_AK47"
|
||||
CrouchAnims(3)="CHWalkR_AK47"
|
||||
WalkAnims(0)="WalkF_AK47"
|
||||
WalkAnims(1)="WalkB_AK47"
|
||||
WalkAnims(2)="WalkL_AK47"
|
||||
WalkAnims(3)="WalkR_AK47"
|
||||
CrouchTurnRightAnim="CH_TurnR_AK47"
|
||||
CrouchTurnLeftAnim="CH_TurnL_AK47"
|
||||
IdleCrouchAnim="CHIdle_AK47"
|
||||
IdleWeaponAnim="Idle_AK47"
|
||||
IdleRestAnim="Idle_AK47"
|
||||
IdleChatAnim="Idle_AK47"
|
||||
IdleHeavyAnim="Idle_AK47"
|
||||
IdleRifleAnim="Idle_AK47"
|
||||
FireAnims(0)="Fire_AK47"
|
||||
FireAnims(1)="Fire_AK47"
|
||||
FireAnims(2)="Fire_AK47"
|
||||
FireAnims(3)="Fire_AK47"
|
||||
FireAltAnims(0)="Fire_AK47"
|
||||
FireAltAnims(1)="Fire_AK47"
|
||||
FireAltAnims(2)="Fire_AK47"
|
||||
FireAltAnims(3)="Fire_AK47"
|
||||
FireCrouchAnims(0)="CHFire_AK47"
|
||||
FireCrouchAnims(1)="CHFire_AK47"
|
||||
FireCrouchAnims(2)="CHFire_AK47"
|
||||
FireCrouchAnims(3)="CHFire_AK47"
|
||||
FireCrouchAltAnims(0)="CHFire_AK47"
|
||||
FireCrouchAltAnims(1)="CHFire_AK47"
|
||||
FireCrouchAltAnims(2)="CHFire_AK47"
|
||||
FireCrouchAltAnims(3)="CHFire_AK47"
|
||||
HitAnims(0)="HitF_AK47"
|
||||
HitAnims(1)="HitB_AK47"
|
||||
HitAnims(2)="HitL_AK47"
|
||||
HitAnims(3)="HitR_AK47"
|
||||
PostFireBlendStandAnim="Blend_AK47"
|
||||
PostFireBlendCrouchAnim="CHBlend_AK47"
|
||||
MeshRef="KF_Weapons3rd_Trip.AK47_3rd"
|
||||
bRapidFire=True
|
||||
bAltRapidFire=True
|
||||
SplashEffect=Class'ROEffects.BulletSplashEmitter'
|
||||
CullDistance=5000.000000
|
||||
}
|
||||
37
kf_sources/NicePack/Classes/NiceAK47Fire.uc
Normal file
37
kf_sources/NicePack/Classes/NiceAK47Fire.uc
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
class NiceAK47Fire extends NiceFire;
|
||||
defaultproperties
|
||||
{
|
||||
zedTimeFireSpeedUp=1.200000
|
||||
ProjectileSpeed=35750.000000
|
||||
FireAimedAnim="Fire_Iron"
|
||||
RecoilRate=0.070000
|
||||
maxVerticalRecoilAngle=210
|
||||
maxHorizontalRecoilAngle=105
|
||||
ShellEjectClass=Class'ROEffects.KFShellEjectAK'
|
||||
ShellEjectBoneName="Shell_eject"
|
||||
bAccuracyBonusForSemiAuto=True
|
||||
bRandomPitchFireSound=False
|
||||
FireSoundRef="KF_AK47Snd.AK47_Fire"
|
||||
StereoFireSoundRef="KF_AK47Snd.AK47_FireST"
|
||||
NoAmmoSoundRef="KF_AK47Snd.AK47_DryFire"
|
||||
DamageType=class'NiceDamTypeAK47AssaultRifle'
|
||||
DamageMin=60
|
||||
DamageMax=60
|
||||
Momentum=8500.000000
|
||||
bPawnRapidFireAnim=True
|
||||
TransientSoundVolume=1.800000
|
||||
FireLoopAnim="Fire"
|
||||
TweenTime=0.025000
|
||||
FireForce="AssaultRifleFire"
|
||||
FireRate=0.109000
|
||||
AmmoClass=class'NiceAK47Ammo'
|
||||
ShakeRotMag=(X=50.000000,Y=50.000000,Z=350.000000)
|
||||
ShakeRotRate=(X=5000.000000,Y=5000.000000,Z=5000.000000)
|
||||
ShakeRotTime=0.750000
|
||||
ShakeOffsetMag=(X=6.000000,Y=3.000000,Z=7.500000)
|
||||
ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000)
|
||||
ShakeOffsetTime=1.250000
|
||||
BotRefireRate=0.990000
|
||||
FlashEmitterClass=Class'ROEffects.MuzzleFlash1stSTG'
|
||||
aimerror=42.000000
|
||||
}
|
||||
27
kf_sources/NicePack/Classes/NiceAK47Pickup.uc
Normal file
27
kf_sources/NicePack/Classes/NiceAK47Pickup.uc
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
class NiceAK47Pickup extends NiceWeaponPickup;
|
||||
defaultproperties
|
||||
{
|
||||
Weight=6.000000
|
||||
cost=750
|
||||
AmmoCost=26
|
||||
BuyClipSize=30
|
||||
PowerValue=40
|
||||
SpeedValue=80
|
||||
RangeValue=50
|
||||
Description="Standard issue military rifle. Equipped with an integrated 2X scope."
|
||||
ItemName="AK47"
|
||||
ItemShortName="AK47"
|
||||
AmmoItemName="7.62mm Ammo"
|
||||
AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo'
|
||||
CorrespondingPerkIndex=3
|
||||
EquipmentCategoryID=2
|
||||
VariantClasses(0)=Class'KFMod.GoldenAK47pickup'
|
||||
VariantClasses(1)=Class'KFMod.NeonAK47Pickup'
|
||||
InventoryType=class'NiceAK47AssaultRifle'
|
||||
PickupMessage="You got the AK47"
|
||||
PickupSound=Sound'KF_AK47Snd.AK47_Pickup'
|
||||
PickupForce="AssaultRiflePickup"
|
||||
StaticMesh=StaticMesh'KF_pickups_Trip.Rifle.AK47_Pickup'
|
||||
CollisionRadius=25.000000
|
||||
CollisionHeight=5.000000
|
||||
}
|
||||
70
kf_sources/NicePack/Classes/NiceAUG_A1AR.uc
Normal file
70
kf_sources/NicePack/Classes/NiceAUG_A1AR.uc
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
class NiceAUG_A1AR extends NiceScopedWeapon;
|
||||
#EXEC OBJ LOAD FILE=HMG_T.utx
|
||||
#EXEC OBJ LOAD FILE=HMG_S.uax
|
||||
#EXEC OBJ LOAD FILE=HMG_A.ukx
|
||||
simulated function AltFire(float F){
|
||||
if(ReadyToFire(0))
|
||||
DoToggle();
|
||||
}
|
||||
exec function SwitchModes(){
|
||||
DoToggle();
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
lenseMaterialID=4
|
||||
scopePortalFOVHigh=17.000000
|
||||
scopePortalFOV=17.000000
|
||||
ZoomMatRef="HMG_T.AUG.AUG-A1_scope_FB"
|
||||
ScriptedTextureFallbackRef="HMG_T.AUG.alpha_lens_64x64"
|
||||
CrosshairTexRef="HMG_T.AUG.AUG-A1_scope"
|
||||
reloadPreEndFrame=0.400000
|
||||
reloadEndFrame=0.645000
|
||||
reloadChargeEndFrame=0.805000
|
||||
reloadMagStartFrame=0.500000
|
||||
reloadChargeStartFrame=0.700000
|
||||
MagazineBone="clip"
|
||||
bHasScope=True
|
||||
ZoomedDisplayFOVHigh=70.000000
|
||||
MagCapacity=30
|
||||
ReloadRate=3.500000
|
||||
ReloadAnim="Reload"
|
||||
ReloadAnimRate=1.000000
|
||||
WeaponReloadAnim="Reload_BullPup"
|
||||
Weight=9.000000
|
||||
bHasAimingMode=True
|
||||
IdleAimAnim="Idle_Iron"
|
||||
StandardDisplayFOV=65.000000
|
||||
SleeveNum=0
|
||||
TraderInfoTexture=Texture'HMG_T.AUG.trader_AUG_A1'
|
||||
bIsTier2Weapon=True
|
||||
MeshRef="HMG_A.AUG_A1_mesh"
|
||||
SkinRefs(0)="KF_Weapons3_Trip_T.hands.Priest_Hands_1st_P"
|
||||
SkinRefs(1)="HMG_T.AUG.body"
|
||||
SkinRefs(2)="HMG_T.AUG.mag"
|
||||
SkinRefs(3)="HMG_T.AUG.Rec"
|
||||
SkinRefs(4)="HMG_T.AUG.alpha_lens_64x64"
|
||||
SelectSoundRef="HMG_S.AUGND.aug_draw"
|
||||
HudImageRef="HMG_T.AUG.AUG_A1_Unselected"
|
||||
SelectedHudImageRef="HMG_T.AUG.AUG_A1_Selected"
|
||||
PlayerIronSightFOV=32.000000
|
||||
ZoomedDisplayFOV=70.000000
|
||||
FireModeClass(0)=class'NiceAUG_A1ARFire'
|
||||
FireModeClass(1)=Class'KFMod.NoFire'
|
||||
PutDownAnim="PutDown"
|
||||
SelectForce="SwitchToAssaultRifle"
|
||||
AIRating=0.650000
|
||||
CurrentRating=0.650000
|
||||
Description="Steyr AUG 1977 Steyr-Daimler-Puch AG & Co KG"
|
||||
DisplayFOV=65.000000
|
||||
Priority=170
|
||||
CustomCrosshair=11
|
||||
CustomCrossHairTextureName="Crosshairs.HUD.Crosshair_Cross5"
|
||||
InventoryGroup=4
|
||||
GroupOffset=3
|
||||
PickupClass=class'NiceAUG_A1ARPickup'
|
||||
PlayerViewOffset=(X=15.000000,Y=12.000000,Z=-2.000000)
|
||||
BobDamping=5.000000
|
||||
AttachmentClass=class'NiceAUG_A1ARAttachment'
|
||||
IconCoords=(X1=253,Y1=146,X2=333,Y2=181)
|
||||
ItemName="Steyr AUG A1"
|
||||
}
|
||||
12
kf_sources/NicePack/Classes/NiceAUG_A1ARAmmo.uc
Normal file
12
kf_sources/NicePack/Classes/NiceAUG_A1ARAmmo.uc
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
class NiceAUG_A1ARAmmo extends NiceAmmo;
|
||||
defaultproperties
|
||||
{
|
||||
WeaponPickupClass=class'NiceAUG_A1ARPickup'
|
||||
AmmoPickupAmount=30
|
||||
MaxAmmo=240
|
||||
InitialAmount=60
|
||||
PickupClass=class'NiceAUG_A1ARAmmoPickup'
|
||||
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
|
||||
IconCoords=(X1=336,Y1=82,X2=382,Y2=125)
|
||||
ItemName="5.56mm NATO"
|
||||
}
|
||||
8
kf_sources/NicePack/Classes/NiceAUG_A1ARAmmoPickup.uc
Normal file
8
kf_sources/NicePack/Classes/NiceAUG_A1ARAmmoPickup.uc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
class NiceAUG_A1ARAmmoPickup extends NiceAmmoPickup;
|
||||
defaultproperties
|
||||
{
|
||||
AmmoAmount=30
|
||||
InventoryType=class'NiceAUG_A1ARAmmo'
|
||||
PickupMessage="5.56mm NATO"
|
||||
StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo'
|
||||
}
|
||||
59
kf_sources/NicePack/Classes/NiceAUG_A1ARAttachment.uc
Normal file
59
kf_sources/NicePack/Classes/NiceAUG_A1ARAttachment.uc
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
class NiceAUG_A1ARAttachment extends NiceAttachment;
|
||||
defaultproperties
|
||||
{
|
||||
mMuzFlashClass=Class'ROEffects.MuzzleFlash3rdMP'
|
||||
mTracerClass=Class'KFMod.KFNewTracer'
|
||||
mShellCaseEmitterClass=Class'KFMod.KFShellSpewer'
|
||||
ShellEjectBoneName="Shell_eject"
|
||||
MovementAnims(0)="JogF_SCAR"
|
||||
MovementAnims(1)="JogB_SCAR"
|
||||
MovementAnims(2)="JogL_SCAR"
|
||||
MovementAnims(3)="JogR_SCAR"
|
||||
TurnLeftAnim="TurnL_SCAR"
|
||||
TurnRightAnim="TurnR_SCAR"
|
||||
CrouchAnims(0)="CHWalkF_SCAR"
|
||||
CrouchAnims(1)="CHWalkB_SCAR"
|
||||
CrouchAnims(2)="CHWalkL_SCAR"
|
||||
CrouchAnims(3)="CHWalkR_SCAR"
|
||||
WalkAnims(0)="WalkF_SCAR"
|
||||
WalkAnims(1)="WalkB_SCAR"
|
||||
WalkAnims(2)="WalkL_SCAR"
|
||||
WalkAnims(3)="WalkR_SCAR"
|
||||
CrouchTurnRightAnim="CH_TurnR_SCAR"
|
||||
CrouchTurnLeftAnim="CH_TurnL_SCAR"
|
||||
IdleCrouchAnim="CHIdle_SCAR"
|
||||
IdleWeaponAnim="Idle_SCAR"
|
||||
IdleRestAnim="Idle_SCAR"
|
||||
IdleChatAnim="Idle_SCAR"
|
||||
IdleHeavyAnim="Idle_SCAR"
|
||||
IdleRifleAnim="Idle_SCAR"
|
||||
FireAnims(0)="Fire_SCAR"
|
||||
FireAnims(1)="Fire_SCAR"
|
||||
FireAnims(2)="Fire_SCAR"
|
||||
FireAnims(3)="Fire_SCAR"
|
||||
FireAltAnims(0)="Fire_SCAR"
|
||||
FireAltAnims(1)="Fire_SCAR"
|
||||
FireAltAnims(2)="Fire_SCAR"
|
||||
FireAltAnims(3)="Fire_SCAR"
|
||||
FireCrouchAnims(0)="CHFire_SCAR"
|
||||
FireCrouchAnims(1)="CHFire_SCAR"
|
||||
FireCrouchAnims(2)="CHFire_SCAR"
|
||||
FireCrouchAnims(3)="CHFire_SCAR"
|
||||
FireCrouchAltAnims(0)="CHFire_SCAR"
|
||||
FireCrouchAltAnims(1)="CHFire_SCAR"
|
||||
FireCrouchAltAnims(2)="CHFire_SCAR"
|
||||
FireCrouchAltAnims(3)="CHFire_SCAR"
|
||||
HitAnims(0)="HitF_SCAR"
|
||||
HitAnims(1)="HitB_SCAR"
|
||||
HitAnims(2)="HitL_SCAR"
|
||||
HitAnims(3)="HitR_SCAR"
|
||||
PostFireBlendStandAnim="Blend_SCAR"
|
||||
PostFireBlendCrouchAnim="CHBlend_SCAR"
|
||||
MeshRef="HMG_A.AUG_A1_3rd"
|
||||
bHeavy=True
|
||||
bRapidFire=True
|
||||
bAltRapidFire=True
|
||||
SplashEffect=Class'ROEffects.BulletSplashEmitter'
|
||||
CullDistance=5000.000000
|
||||
DrawScale=0.800000
|
||||
}
|
||||
35
kf_sources/NicePack/Classes/NiceAUG_A1ARFire.uc
Normal file
35
kf_sources/NicePack/Classes/NiceAUG_A1ARFire.uc
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
class NiceAUG_A1ARFire extends NiceHeavyFire;
|
||||
defaultproperties
|
||||
{
|
||||
ProjectileSpeed=48500.000000
|
||||
FireAimedAnim="Idle_Iron"
|
||||
RecoilRate=0.080000
|
||||
maxVerticalRecoilAngle=500
|
||||
maxHorizontalRecoilAngle=250
|
||||
ShellEjectClass=Class'ROEffects.KFShellEjectBullpup'
|
||||
ShellEjectBoneName="Shell_eject"
|
||||
bAccuracyBonusForSemiAuto=True
|
||||
FireSoundRef="HMG_S.AUGND.aug_fire"
|
||||
StereoFireSoundRef="HMG_S.AUGND.aug_fire"
|
||||
NoAmmoSoundRef="HMG_S.AUGND.aug_empty"
|
||||
DamageType=class'NiceDamTypeAUG_A1AR'
|
||||
DamageMin=105
|
||||
DamageMax=105
|
||||
Momentum=12000.000000
|
||||
bPawnRapidFireAnim=True
|
||||
TransientSoundVolume=1.800000
|
||||
FireLoopAnim="Fire"
|
||||
TweenTime=0.025000
|
||||
FireForce="AssaultRifleFire"
|
||||
FireRate=0.200000
|
||||
AmmoClass=class'NiceAUG_A1ARAmmo'
|
||||
ShakeRotMag=(X=75.000000,Y=75.000000,Z=250.000000)
|
||||
ShakeRotRate=(X=10000.000000,Y=10000.000000,Z=10000.000000)
|
||||
ShakeRotTime=0.500000
|
||||
ShakeOffsetMag=(X=6.000000,Y=3.000000,Z=10.000000)
|
||||
ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000)
|
||||
ShakeOffsetTime=1.000000
|
||||
BotRefireRate=0.990000
|
||||
FlashEmitterClass=Class'ROEffects.MuzzleFlash1stSTG'
|
||||
aimerror=42.000000
|
||||
}
|
||||
24
kf_sources/NicePack/Classes/NiceAUG_A1ARPickup.uc
Normal file
24
kf_sources/NicePack/Classes/NiceAUG_A1ARPickup.uc
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
class NiceAUG_A1ARPickup extends NiceWeaponPickup;
|
||||
defaultproperties
|
||||
{
|
||||
cost=1000
|
||||
Weight=9.000000
|
||||
AmmoCost=80
|
||||
BuyClipSize=25
|
||||
PowerValue=45
|
||||
SpeedValue=65
|
||||
RangeValue=90
|
||||
Description="Steyr AUG 1977 Steyr-Daimler-Puch AG & Co KG"
|
||||
ItemName="Steyr AUG A1"
|
||||
ItemShortName="AUG A1"
|
||||
AmmoItemName="Rounds 5.56mm NATO"
|
||||
CorrespondingPerkIndex=1
|
||||
EquipmentCategoryID=2
|
||||
InventoryType=class'NiceAUG_A1AR'
|
||||
PickupMessage="You picked up the Steyr AUG A1"
|
||||
PickupSound=Sound'HMG_S.AUG.aug_pickup'
|
||||
PickupForce="AssaultRiflePickup"
|
||||
StaticMesh=StaticMesh'HMG_A.AUG_A1_st'
|
||||
CollisionRadius=30.000000
|
||||
CollisionHeight=5.000000
|
||||
}
|
||||
25
kf_sources/NicePack/Classes/NiceAbilitiesAdapter.uc
Normal file
25
kf_sources/NicePack/Classes/NiceAbilitiesAdapter.uc
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
//==============================================================================
|
||||
// NicePack / NiceAbilitiesAdapter
|
||||
//==============================================================================
|
||||
// Temporary stand-in for future functionality.
|
||||
// Use this class to catch events from players' abilities.
|
||||
//==============================================================================
|
||||
// 'Nice pack' source
|
||||
// Do whatever the fuck you want with it
|
||||
// Author: dkanus
|
||||
// E-mail: dkanus@gmail.com
|
||||
//==============================================================================
|
||||
class NiceAbilitiesAdapter extends Object;
|
||||
var LevelInfo level;
|
||||
static function AbilityActivated( string abilityID,
|
||||
NicePlayerController relatedPlayer);
|
||||
static function AbilityAdded( string abilityID,
|
||||
NicePlayerController relatedPlayer);
|
||||
static function AbilityRemoved( string abilityID,
|
||||
NicePlayerController relatedPlayer);
|
||||
static function ModAbilityCooldown( string abilityID,
|
||||
NicePlayerController relatedPlayer,
|
||||
out float cooldown);
|
||||
defaultproperties
|
||||
{
|
||||
}
|
||||
79
kf_sources/NicePack/Classes/NiceAbilitiesEvents.uc
Normal file
79
kf_sources/NicePack/Classes/NiceAbilitiesEvents.uc
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
//==============================================================================
|
||||
// NicePack / NiceAbilitiesEvents
|
||||
//==============================================================================
|
||||
// Temporary stand-in for future functionality.
|
||||
//==============================================================================
|
||||
// 'Nice pack' source
|
||||
// Do whatever the fuck you want with it
|
||||
// Author: dkanus
|
||||
// E-mail: dkanus@gmail.com
|
||||
//==============================================================================
|
||||
class NiceAbilitiesEvents extends Object;
|
||||
var array< class<NiceAbilitiesAdapter> > adapters;
|
||||
// If adapter was already added also returns 'false'.
|
||||
static function bool AddAdapter(class<NiceAbilitiesAdapter> newAdapter,
|
||||
optional LevelInfo level){
|
||||
local int i;
|
||||
if(newAdapter == none) return false;
|
||||
for(i = 0;i < default.adapters.length;i ++)
|
||||
if(default.adapters[i] == newAdapter)
|
||||
return false;
|
||||
newAdapter.default.level = level;
|
||||
default.adapters[default.adapters.length] = newAdapter;
|
||||
return true;
|
||||
}
|
||||
// If adapter wasn't even present also returns 'false'.
|
||||
static function bool RemoveAdapter(class<NiceAbilitiesAdapter> adapter){
|
||||
local int i;
|
||||
if(adapter == none) return false;
|
||||
for(i = 0;i < default.adapters.length;i ++){
|
||||
if(default.adapters[i] == adapter){
|
||||
default.adapters.Remove(i, 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static function CallAbilityActivated
|
||||
(
|
||||
string abilityID,
|
||||
NicePlayerController relatedPlayer
|
||||
){
|
||||
local int i;
|
||||
for(i = 0;i < default.adapters.length;i ++)
|
||||
default.adapters[i].static.AbilityActivated(abilityID, relatedPlayer);
|
||||
}
|
||||
static function CallAbilityAdded
|
||||
(
|
||||
string abilityID,
|
||||
NicePlayerController relatedPlayer
|
||||
){
|
||||
local int i;
|
||||
for(i = 0;i < default.adapters.length;i ++)
|
||||
default.adapters[i].static.AbilityAdded(abilityID, relatedPlayer);
|
||||
}
|
||||
static function CallAbilityRemoved
|
||||
(
|
||||
string abilityID,
|
||||
NicePlayerController relatedPlayer
|
||||
){
|
||||
local int i;
|
||||
for(i = 0;i < default.adapters.length;i ++)
|
||||
default.adapters[i].static.AbilityRemoved(abilityID, relatedPlayer);
|
||||
}
|
||||
static function CallModAbilityCooldown
|
||||
(
|
||||
string abilityID,
|
||||
NicePlayerController relatedPlayer,
|
||||
out float cooldown
|
||||
){
|
||||
local int i;
|
||||
for(i = 0;i < default.adapters.length;i ++){
|
||||
default.adapters[i].static.ModAbilityCooldown( abilityID,
|
||||
relatedPlayer,
|
||||
cooldown);
|
||||
}
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
}
|
||||
178
kf_sources/NicePack/Classes/NiceAbilityManager.uc
Normal file
178
kf_sources/NicePack/Classes/NiceAbilityManager.uc
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
//==============================================================================
|
||||
// NicePack / NiceAbilityManager
|
||||
//==============================================================================
|
||||
// Class that manager active abilities, introduced along with a NicePack.
|
||||
// Can support at most 5 ('maxAbilitiesAmount') different abilities at once.
|
||||
// NICETODO: refactor later
|
||||
//==============================================================================
|
||||
// 'Nice pack' source
|
||||
// Do whatever the fuck you want with it
|
||||
// Author: dkanus
|
||||
// E-mail: dkanus@gmail.com
|
||||
//==============================================================================
|
||||
class NiceAbilityManager extends Actor;
|
||||
var const int maxAbilitiesAmount;
|
||||
// Defines a list of all possible ability's states
|
||||
enum EAbilityState{
|
||||
// Ability is ready to use
|
||||
ASTATE_READY,
|
||||
// Ability is being used
|
||||
ASTATE_ACTIVE,
|
||||
// Ability is on cooldown
|
||||
ASTATE_COOLDOWN
|
||||
};
|
||||
// Describes all the necessary information about an ability
|
||||
struct NiceAbilityDescription{
|
||||
// Ability's ID, supposed to be unique per ability,
|
||||
// but no checks are enforced yet
|
||||
var string ID;
|
||||
// Image to be used as an ability's icon
|
||||
var Texture icon;
|
||||
// Default cooldown duration
|
||||
var int cooldownLength;
|
||||
// Can ability be canceled once activated?
|
||||
var bool canBeCancelled;
|
||||
};
|
||||
// Complete description of current status of an ability,
|
||||
// including it's complete description.
|
||||
struct NiceAbilityStatus{
|
||||
// Complete description of ability in question
|
||||
var NiceAbilityDescription description;
|
||||
// Current cooldown value
|
||||
var int cooldown;
|
||||
// Current state of an ability
|
||||
var EAbilityState myState;
|
||||
};
|
||||
var NiceAbilityStatus currentAbilities[5];
|
||||
var int currentAbilitiesAmount;
|
||||
// Refers to the player whose abilities we manage
|
||||
var NicePlayerController relatedPlayer;
|
||||
var const class<NiceAbilitiesEvents> events;
|
||||
// Unfortunately this hackk is required to force replication of structure array
|
||||
var int hackCounter;
|
||||
replication{
|
||||
reliable if(Role == ROLE_Authority)
|
||||
currentAbilities, currentAbilitiesAmount, hackCounter;
|
||||
}
|
||||
simulated function PostBeginPlay(){
|
||||
relatedPlayer = NicePlayerController(owner);
|
||||
}
|
||||
function AddAbility(NiceAbilityDescription description){
|
||||
local int i;
|
||||
local NiceAbilityStatus newRecord;
|
||||
if(currentAbilitiesAmount >= maxAbilitiesAmount) return;
|
||||
for(i = 0;i < currentAbilitiesAmount;i ++)
|
||||
if(currentAbilities[i].description.ID ~= description.ID)
|
||||
return;
|
||||
newRecord.description = description;
|
||||
newRecord.cooldown = 0;
|
||||
newRecord.myState = ASTATE_READY;
|
||||
currentAbilities[currentAbilitiesAmount] = newRecord;
|
||||
currentAbilitiesAmount += 1;
|
||||
events.static.CallAbilityAdded(description.ID, relatedPlayer);
|
||||
netUpdateTime = level.timeSeconds - 1;
|
||||
}
|
||||
function RemoveAbility(string abilityID){
|
||||
local int i, j;
|
||||
local bool wasRemoved;
|
||||
j = 0;
|
||||
for(i = 0;i < currentAbilitiesAmount;i ++){
|
||||
if(currentAbilities[i].description.ID ~= abilityID){
|
||||
wasRemoved = true;
|
||||
continue;
|
||||
}
|
||||
currentAbilities[j] = currentAbilities[i];
|
||||
j += 1;
|
||||
}
|
||||
currentAbilitiesAmount = j;
|
||||
if(wasRemoved)
|
||||
events.static.CallAbilityRemoved(abilityID, relatedPlayer);
|
||||
netUpdateTime = level.timeSeconds - 1;
|
||||
}
|
||||
function ClearAbilities(){
|
||||
currentAbilitiesAmount = 0;
|
||||
netUpdateTime = level.timeSeconds - 1;
|
||||
}
|
||||
// Returns index of the ability with a given name.
|
||||
// Returns '-1' if such ability doesn't exist.
|
||||
simulated function int GetAbilityIndex(string abilityID){
|
||||
local int i;
|
||||
for(i = 0;i < currentAbilitiesAmount;i ++)
|
||||
if(currentAbilities[i].description.ID ~= abilityID)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
simulated function bool IsAbilityActive(string abilityID){
|
||||
local int index;
|
||||
index = GetAbilityIndex(abilityID);
|
||||
if(index < 0)
|
||||
return false;
|
||||
return (currentAbilities[index].myState == ASTATE_ACTIVE);
|
||||
}
|
||||
// Sets ability to a proper state.
|
||||
// Does nothing if ability is already in a specified state.
|
||||
// Setting active ability to a ready state is only allowed
|
||||
// if ability can be canceled.
|
||||
// Updates cooldown to full length if new state is 'ASTATE_COOLDOWN'.
|
||||
function SetAbilityState(int abilityIndex, EAbilityState newState){
|
||||
local float cooldown;
|
||||
local EAbilityState currentState;
|
||||
if(abilityIndex < 0 || abilityIndex >= currentAbilitiesAmount) return;
|
||||
currentState = currentAbilities[abilityIndex].myState;
|
||||
if(currentState == newState)
|
||||
return;
|
||||
if( currentState == ASTATE_ACTIVE && newState == ASTATE_READY
|
||||
&& !currentAbilities[abilityIndex].description.canBeCancelled)
|
||||
return;
|
||||
currentAbilities[abilityIndex].myState = newState;
|
||||
if(newState == ASTATE_COOLDOWN){
|
||||
cooldown = currentAbilities[abilityIndex].description.cooldownLength;
|
||||
events.static.CallModAbilityCooldown(
|
||||
currentAbilities[abilityIndex].description.ID,
|
||||
relatedPlayer,
|
||||
cooldown
|
||||
);
|
||||
currentAbilities[abilityIndex].cooldown = cooldown;
|
||||
}
|
||||
hackCounter ++;
|
||||
netUpdateTime = level.timeSeconds - 1;
|
||||
// Fire off events
|
||||
if(newState == ASTATE_ACTIVE){
|
||||
events.static.CallAbilityActivated(
|
||||
currentAbilities[abilityIndex].description.ID,
|
||||
relatedPlayer
|
||||
);
|
||||
}
|
||||
}
|
||||
// Changes ability's cooldown by a given amount.
|
||||
// If this brings cooldown to zero or below -
|
||||
// resets current ability to a 'ready' (ASTATE_READY) state.
|
||||
function AddToCooldown(int abilityIndex, int delta){
|
||||
if(abilityIndex < 0 || abilityIndex >= currentAbilitiesAmount) return;
|
||||
if(currentAbilities[abilityIndex].myState != ASTATE_COOLDOWN) return;
|
||||
currentAbilities[abilityIndex].cooldown += delta;
|
||||
if(currentAbilities[abilityIndex].cooldown <= 0)
|
||||
SetAbilityState(abilityIndex, ASTATE_READY);
|
||||
hackCounter ++;
|
||||
}
|
||||
|
||||
function AddToAllCooldowns(int delta){
|
||||
local int i;
|
||||
|
||||
for (i = 0; i < currentAbilitiesAmount; i += 1) {
|
||||
if (currentAbilities[i].myState == ASTATE_COOLDOWN) {
|
||||
currentAbilities[i].cooldown += delta;
|
||||
if(currentAbilities[i].cooldown <= 0) {
|
||||
SetAbilityState(i, ASTATE_READY);
|
||||
}
|
||||
}
|
||||
}
|
||||
hackCounter ++;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
maxAbilitiesAmount=5
|
||||
Events=class'NiceAbilitiesEvents'
|
||||
DrawType=DT_None
|
||||
}
|
||||
12
kf_sources/NicePack/Classes/NiceAmmo.uc
Normal file
12
kf_sources/NicePack/Classes/NiceAmmo.uc
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
class NiceAmmo extends KFAmmunition;
|
||||
var class<NiceWeaponPickup> WeaponPickupClass;
|
||||
function UpdateAmmoAmount(){
|
||||
MaxAmmo = Default.MaxAmmo;
|
||||
if(KFPawn(Owner) != none && KFPlayerReplicationInfo(KFPawn(Owner).PlayerReplicationInfo) != none &&
|
||||
KFPlayerReplicationInfo(KFPawn(Owner).PlayerReplicationInfo).ClientVeteranSkill != none)
|
||||
MaxAmmo = float(MaxAmmo) * KFPlayerReplicationInfo(KFPawn(Owner).PlayerReplicationInfo).ClientVeteranSkill.Static.AddExtraAmmoFor(KFPlayerReplicationInfo(KFPawn(Owner).PlayerReplicationInfo), Class);
|
||||
AmmoAmount = Min(AmmoAmount, MaxAmmo);
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
}
|
||||
45
kf_sources/NicePack/Classes/NiceAmmoPickup.uc
Normal file
45
kf_sources/NicePack/Classes/NiceAmmoPickup.uc
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
class NiceAmmoPickup extends ScrnAmmoPickup;
|
||||
state Pickup
|
||||
{
|
||||
// When touched by an actor.
|
||||
function Touch(Actor Other){
|
||||
local Inventory CurInv;
|
||||
local bool bPickedUp;
|
||||
local int AmmoPickupAmount;
|
||||
if(Pawn(Other) != none && Pawn(Other).bCanPickupInventory && Pawn(Other).Controller != none && FastTrace(Other.Location, Location)){
|
||||
for(CurInv = Other.Inventory;CurInv != none;CurInv = CurInv.Inventory){
|
||||
|
||||
if(KFAmmunition(CurInv) != none && KFAmmunition(CurInv).bAcceptsAmmoPickups){
|
||||
if(KFAmmunition(CurInv).AmmoPickupAmount > 0){
|
||||
if(KFAmmunition(CurInv).AmmoAmount < KFAmmunition(CurInv).MaxAmmo){
|
||||
if(KFPlayerReplicationInfo(Pawn(Other).PlayerReplicationInfo) != none && KFPlayerReplicationInfo(Pawn(Other).PlayerReplicationInfo).ClientVeteranSkill != none)
|
||||
AmmoPickupAmount = float(KFAmmunition(CurInv).AmmoPickupAmount) * KFPlayerReplicationInfo(Pawn(Other).PlayerReplicationInfo).ClientVeteranSkill.static.GetAmmoPickupMod(KFPlayerReplicationInfo(Pawn(Other).PlayerReplicationInfo), KFAmmunition(CurInv));
|
||||
else
|
||||
AmmoPickupAmount = KFAmmunition(CurInv).AmmoPickupAmount;
|
||||
|
||||
KFAmmunition(CurInv).AmmoAmount = Min(KFAmmunition(CurInv).MaxAmmo, KFAmmunition(CurInv).AmmoAmount + AmmoPickupAmount);
|
||||
bPickedUp = true;
|
||||
}
|
||||
}
|
||||
else if(KFAmmunition(CurInv).AmmoAmount < KFAmmunition(CurInv).MaxAmmo){
|
||||
bPickedUp = true;
|
||||
if(FRand() <= (1.0 / Level.Game.GameDifficulty))
|
||||
KFAmmunition(CurInv).AmmoAmount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(bPickedUp){
|
||||
|
||||
AnnouncePickup(Pawn(Other));
|
||||
GotoState('Sleeping', 'Begin');
|
||||
|
||||
if(KFGameType(Level.Game) != none)
|
||||
KFGameType(Level.Game).AmmoPickedUp(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
}
|
||||
19
kf_sources/NicePack/Classes/NiceArchivator.uc
Normal file
19
kf_sources/NicePack/Classes/NiceArchivator.uc
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//==============================================================================
|
||||
// NicePack / NiceArchivator
|
||||
//==============================================================================
|
||||
// "Compresses" and "decompresses" parts of NicePlain data into
|
||||
// string for replication.
|
||||
//==============================================================================
|
||||
// Class hierarchy: Object > NiceArchivator
|
||||
//==============================================================================
|
||||
// 'Nice pack' source
|
||||
// Do whatever the fuck you want with it
|
||||
// Author: dkanus
|
||||
// E-mail: dkanus@gmail.com
|
||||
//==============================================================================
|
||||
|
||||
class NiceArchivator extends Object;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
}
|
||||
306
kf_sources/NicePack/Classes/NiceAssaultRifle.uc
Normal file
306
kf_sources/NicePack/Classes/NiceAssaultRifle.uc
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
class NiceAssaultRifle extends NiceWeapon;
|
||||
var bool newStatesLoaded;
|
||||
var bool bAutoFireEnabled;
|
||||
var bool bSemiAutoFireEnabled;
|
||||
var bool bBurstFireEnabled;
|
||||
var bool bIsBursting;
|
||||
var bool bIsAltSwitches;
|
||||
var bool bMustSwitchMode; // Switch between auto and semi-auto/burst modes as soon as possible
|
||||
var Pawn rememberedOwner;
|
||||
enum EFireType{
|
||||
ETYPE_NONE,
|
||||
ETYPE_AUTO,
|
||||
ETYPE_SEMI,
|
||||
ETYPE_BURST
|
||||
};
|
||||
var EFireType MainFire;
|
||||
var EFireType SndFire;
|
||||
var EFireType PendingFire;
|
||||
replication
|
||||
{
|
||||
reliable if(Role < ROLE_Authority)
|
||||
ServerForceBurst, ServerApplyFireModes, ServerChangeFireTypes;
|
||||
reliable if(Role == ROLE_Authority)
|
||||
MainFire, SndFire, PendingFire, ClientNiceChangeFireMode, ClientChangeBurstLength;
|
||||
}
|
||||
simulated function EFireType GetComplimentaryFire(EFireType type){
|
||||
if(type == ETYPE_AUTO || type == ETYPE_none)
|
||||
return ETYPE_AUTO;
|
||||
if(type == ETYPE_SEMI)
|
||||
return ETYPE_BURST;
|
||||
return ETYPE_SEMI;
|
||||
}
|
||||
simulated function int AmountOfActiveModes(){
|
||||
if(bAutoFireEnabled && bSemiAutoFireEnabled && bBurstFireEnabled)
|
||||
return 3;
|
||||
else if(!bAutoFireEnabled && !bSemiAutoFireEnabled && !bBurstFireEnabled)
|
||||
return 0;
|
||||
else if( (bAutoFireEnabled && bSemiAutoFireEnabled) || (bAutoFireEnabled && bBurstFireEnabled) || (bSemiAutoFireEnabled && bBurstFireEnabled) )
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
function ServerApplyFireModes(){
|
||||
local NiceFire niceRifleFire;
|
||||
local NicePlayerController nicePlayer;
|
||||
niceRifleFire = NiceFire(FireMode[0]);
|
||||
if(Instigator != none)
|
||||
nicePlayer = NicePlayerController(Instigator.Controller);
|
||||
if(niceRifleFire == none)
|
||||
return;
|
||||
if(MainFire == ETYPE_AUTO)
|
||||
niceRifleFire.bWaitForRelease = false;
|
||||
else if(MainFire == ETYPE_SEMI){
|
||||
niceRifleFire.bSemiMustBurst = false;
|
||||
niceRifleFire.bWaitForRelease = true;
|
||||
}
|
||||
else if(MainFire == ETYPE_BURST){
|
||||
niceRifleFire.bSemiMustBurst = true;
|
||||
niceRifleFire.bWaitForRelease = true;
|
||||
niceRifleFire.currentContext.burstLength = niceRifleFire.MaxBurstLength;
|
||||
if(SndFire == ETYPE_SEMI)
|
||||
SndFire = ETYPE_BURST;
|
||||
}
|
||||
if(nicePlayer != none && !nicePlayer.bFlagAltSwitchesModes){
|
||||
if(SndFire == ETYPE_SEMI)
|
||||
niceRifleFire.currentContext.burstLength = 1;
|
||||
else if(SndFire == ETYPE_BURST)
|
||||
niceRifleFire.currentContext.burstLength = niceRifleFire.MaxBurstLength;
|
||||
}
|
||||
if(!bIsReloading && IsFiring()){
|
||||
StopFire(0);
|
||||
StopFire(1);
|
||||
}
|
||||
ClientNiceChangeFireMode(niceRifleFire.bWaitForRelease, niceRifleFire.bSemiMustBurst);
|
||||
ClientChangeBurstLength(niceRifleFire.currentContext.burstLength);
|
||||
}
|
||||
simulated function ResetFireModes(){
|
||||
local int modesCount;
|
||||
local NicePlayerController nicePlayer;
|
||||
modesCount = AmountOfActiveModes();
|
||||
nicePlayer = NicePlayerController(Instigator.Controller);
|
||||
if(modesCount <= 0 || nicePlayer == none)
|
||||
return;
|
||||
if(nicePlayer.bFlagAltSwitchesModes){
|
||||
if(modesCount == 1){
|
||||
if(bAutoFireEnabled)
|
||||
MainFire = ETYPE_AUTO;
|
||||
else if(bSemiAutoFireEnabled)
|
||||
MainFire = ETYPE_SEMI;
|
||||
else if(bBurstFireEnabled)
|
||||
MainFire = ETYPE_BURST;
|
||||
}
|
||||
else if(modesCount == 2){
|
||||
if(bAutoFireEnabled){
|
||||
MainFire = ETYPE_AUTO;
|
||||
if(bSemiAutoFireEnabled)
|
||||
PendingFire = ETYPE_SEMI;
|
||||
else if(bBurstFireEnabled)
|
||||
PendingFire = ETYPE_BURST;
|
||||
}
|
||||
else{
|
||||
MainFire = ETYPE_SEMI;
|
||||
PendingFire = ETYPE_BURST;
|
||||
}
|
||||
}
|
||||
else{
|
||||
MainFire = ETYPE_AUTO;
|
||||
PendingFire = ETYPE_SEMI;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(modesCount == 1){
|
||||
if(bAutoFireEnabled)
|
||||
MainFire = ETYPE_AUTO;
|
||||
else if(bSemiAutoFireEnabled)
|
||||
MainFire = ETYPE_SEMI;
|
||||
else if(bBurstFireEnabled)
|
||||
MainFire = ETYPE_BURST;
|
||||
SndFire = ETYPE_none;
|
||||
}
|
||||
else if(modesCount == 2){
|
||||
if(bAutoFireEnabled){
|
||||
MainFire = ETYPE_AUTO;
|
||||
if(bSemiAutoFireEnabled)
|
||||
SndFire = ETYPE_SEMI;
|
||||
else if(bBurstFireEnabled)
|
||||
SndFire = ETYPE_BURST;
|
||||
}
|
||||
else{
|
||||
MainFire = ETYPE_SEMI;
|
||||
SndFire = ETYPE_BURST;
|
||||
}
|
||||
}
|
||||
else{
|
||||
MainFire = ETYPE_AUTO;
|
||||
SndFire = ETYPE_SEMI;
|
||||
}
|
||||
}
|
||||
ServerChangeFireTypes(MainFire, SndFire, PendingFire);
|
||||
ServerApplyFireModes();
|
||||
}
|
||||
function ServerChangeFireTypes(EFireType newMain, EFireType newSnd, EFireType newPending){
|
||||
MainFire = newMain;
|
||||
SndFire = newSnd;
|
||||
PendingFire = newPending;
|
||||
}
|
||||
function ServerForceBurst(){
|
||||
local NiceFire niceRifleFire;
|
||||
niceRifleFire = NiceFire(FireMode[0]);
|
||||
if(niceRifleFire != none)
|
||||
niceRifleFire.DoBurst();
|
||||
}
|
||||
// Use alt fire to switch fire modes
|
||||
simulated function AltFire(float F){
|
||||
local NiceFire niceRifleFire;
|
||||
local NicePlayerController nicePlayer;
|
||||
niceRifleFire = NiceFire(FireMode[0]);
|
||||
nicePlayer = NicePlayerController(Instigator.Controller);
|
||||
if(nicePlayer != none && niceRifleFire != none && SndFire != ETYPE_NONE){
|
||||
if(FireModeClass[1] == class'KFMod.NoFire'){
|
||||
if(nicePlayer.bFlagAltSwitchesModes)
|
||||
SwitchModes();
|
||||
else{
|
||||
niceRifleFire.DoBurst();
|
||||
ServerForceBurst();
|
||||
super.AltFire(F);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.AltFire(F);
|
||||
}
|
||||
exec simulated function SwitchModes(){
|
||||
if(Role < ROLE_Authority && AmountOfActiveModes() > 1)
|
||||
bMustSwitchMode = !bMustSwitchMode;
|
||||
}
|
||||
simulated function DoToggle(){
|
||||
local EFireType tempType;
|
||||
local PlayerController player;
|
||||
if(IsFiring())
|
||||
return;
|
||||
player = Level.GetLocalPlayerController();
|
||||
if(player != none && AmountOfActiveModes() > 1){
|
||||
tempType = MainFire;
|
||||
MainFire = PendingFire;
|
||||
PendingFire = tempType;
|
||||
player.bFire = 0;
|
||||
player.bAltFire = 0;
|
||||
ServerChangeFireTypes(MainFire, SndFire, PendingFire);
|
||||
ServerApplyFireModes();
|
||||
PlayOwnedSound(ToggleSound, SLOT_none, 2.0,,,, false);
|
||||
if(MainFire == ETYPE_AUTO)
|
||||
player.ReceiveLocalizedMessage(class'NiceAssaultRifleMessage', 1);
|
||||
else if(MainFire == ETYPE_SEMI)
|
||||
player.ReceiveLocalizedMessage(class'NiceAssaultRifleMessage', 0);
|
||||
else if(MainFire == ETYPE_BURST)
|
||||
player.ReceiveLocalizedMessage(class'NiceAssaultRifleMessage', 2);
|
||||
}
|
||||
}
|
||||
simulated function SecondDoToggle(){
|
||||
local EFireType choosenType;
|
||||
local NiceFire niceRifleFire;
|
||||
local NicePlayerController nicePlayer;
|
||||
if(FireModeClass[1] != class'KFMod.NoFire'){
|
||||
DoToggle();
|
||||
return;
|
||||
}
|
||||
niceRifleFire = NiceFire(FireMode[0]);
|
||||
nicePlayer = NicePlayerController(Instigator.Controller);
|
||||
if(IsFiring() || AmountOfActiveModes() < 3 || nicePlayer == none || niceRifleFire == none)
|
||||
return;
|
||||
if(nicePlayer.bFlagAltSwitchesModes){
|
||||
if(MainFire == ETYPE_AUTO){
|
||||
PendingFire = GetComplimentaryFire(PendingFire);
|
||||
choosenType = PendingFire;
|
||||
}
|
||||
else{
|
||||
MainFire = GetComplimentaryFire(MainFire);
|
||||
choosenType = MainFire;
|
||||
}
|
||||
}
|
||||
else{
|
||||
SndFire = GetComplimentaryFire(SndFire);
|
||||
choosenType = SndFire;
|
||||
}
|
||||
ServerChangeFireTypes(MainFire, SndFire, PendingFire);
|
||||
ServerApplyFireModes();
|
||||
PlayOwnedSound(ToggleSound, SLOT_none, 2.0,,,, false);
|
||||
if(choosenType == ETYPE_SEMI)
|
||||
nicePlayer.ReceiveLocalizedMessage(class'NiceAssaultRifleMessage', 4);
|
||||
else
|
||||
nicePlayer.ReceiveLocalizedMessage(class'NiceAssaultRifleMessage', 5);
|
||||
}
|
||||
simulated function ClientNiceChangeFireMode(bool bNewWaitForRelease, bool bNewSemiMustBurst){
|
||||
local NiceFire niceF;
|
||||
if(!bIsReloading && IsFiring()){
|
||||
StopFire(0);
|
||||
StopFire(1);
|
||||
}
|
||||
niceF = NiceFire(FireMode[0]);
|
||||
FireMode[0].bWaitForRelease = bNewWaitForRelease;
|
||||
FireMode[0].bNowWaiting = bNewWaitForRelease;
|
||||
if(niceF != none)
|
||||
niceF.bSemiMustBurst = bNewSemiMustBurst;
|
||||
}
|
||||
simulated function ClientChangeBurstLength(int newBurstLength){
|
||||
if(NiceFire(FireMode[0]) != none)
|
||||
NiceFire(FireMode[0]).currentContext.burstLength = newBurstLength;
|
||||
}
|
||||
simulated function bool AltFireCanForceInterruptReload(){
|
||||
local NicePlayerController nicePlayer;
|
||||
nicePlayer = NicePlayerController(Instigator.Controller);
|
||||
if(nicePlayer != none)
|
||||
return (!nicePlayer.bFlagAltSwitchesModes) && (GetMagazineAmmo() > 0);
|
||||
return false;
|
||||
}
|
||||
simulated function WeaponTick(float dt){
|
||||
local NicePlayerController nicePlayer;
|
||||
super.WeaponTick(dt);
|
||||
if(bMustSwitchMode && FireMode[0].NextFireTime /*+ 0.1*/ < Level.TimeSeconds && Role < ROLE_Authority){
|
||||
DoToggle();
|
||||
bMustSwitchMode = false;
|
||||
}
|
||||
nicePlayer = NicePlayerController(Instigator.Controller);
|
||||
if(Role == ROLE_Authority && nicePlayer != none && (bIsAltSwitches != nicePlayer.bFlagAltSwitchesModes || (rememberedOwner != Instigator))){
|
||||
if(newStatesLoaded)
|
||||
ServerApplyFireModes();
|
||||
else
|
||||
ResetFireModes();
|
||||
bIsAltSwitches = nicePlayer.bFlagAltSwitchesModes;
|
||||
rememberedOwner = Instigator;
|
||||
}
|
||||
}
|
||||
function NicePlainData.Data GetNiceData(){
|
||||
local NicePlainData.Data transferData;
|
||||
transferData = super.GetNiceData();
|
||||
class'NicePlainData'.static.SetInt(transferData, "MainFire", int(MainFire));
|
||||
class'NicePlainData'.static.SetInt(transferData, "SndFire", int(SndFire));
|
||||
class'NicePlainData'.static.SetInt(transferData, "PendingFire", int(PendingFire));
|
||||
return transferData;
|
||||
}
|
||||
function SetNiceData(NicePlainData.Data transferData, optional NiceHumanPawn newOwner){
|
||||
local EFireType newFireType;
|
||||
super.SetNiceData(transferData, newOwner);
|
||||
newStatesLoaded = false;
|
||||
if(class'NicePlainData'.static.LookupVar(transferData, "MainFire") < 0)
|
||||
ResetFireModes();
|
||||
else{
|
||||
newFireType = EFireType(class'NicePlainData'.static.GetInt(transferData, "MainFire"));
|
||||
MainFire = newFireType;
|
||||
newFireType = EFireType(class'NicePlainData'.static.GetInt(transferData, "SndFire"));
|
||||
SndFire = newFireType;
|
||||
newFireType = EFireType(class'NicePlainData'.static.GetInt(transferData, "PendingFire"));
|
||||
PendingFire = newFireType;
|
||||
newStatesLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bAutoFireEnabled=True
|
||||
bSemiAutoFireEnabled=True
|
||||
MainFire=ETYPE_AUTO
|
||||
SndFire=ETYPE_SEMI
|
||||
PendingFire=ETYPE_BURST
|
||||
bUseFlashlightToToggle=True
|
||||
}
|
||||
9
kf_sources/NicePack/Classes/NiceAssaultRifleMessage.uc
Normal file
9
kf_sources/NicePack/Classes/NiceAssaultRifleMessage.uc
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
class NiceAssaultRifleMessage extends BullpupSwitchMessage;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
SwitchMessage(2)="Set to Burst Fire."
|
||||
SwitchMessage(3)="Set to 5-Burst Fire."
|
||||
SwitchMessage(4)="Secondary mode now set to Semi-Automatic."
|
||||
SwitchMessage(5)="Secondary mode now set to Burst Fire."
|
||||
}
|
||||
131
kf_sources/NicePack/Classes/NiceAttachment.uc
Normal file
131
kf_sources/NicePack/Classes/NiceAttachment.uc
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
class NiceAttachment extends ScrnLaserWeaponAttachment
|
||||
abstract;
|
||||
var array<string> SkinRefs;
|
||||
var bool bSpawnLight;
|
||||
var bool bSecondaryModeNoEffects;
|
||||
static function PreloadAssets(optional KFWeaponAttachment Spawned){
|
||||
local int i;
|
||||
if(default.Mesh == none && default.MeshRef != "")
|
||||
UpdateDefaultMesh(Mesh(DynamicLoadObject(default.MeshRef, class'Mesh', true)));
|
||||
if(default.AmbientSound == none && default.AmbientSoundRef != "")
|
||||
default.AmbientSound = sound(DynamicLoadObject(default.AmbientSoundRef, class'Sound', true));
|
||||
if(Spawned != none){
|
||||
Spawned.LinkMesh(default.Mesh);
|
||||
Spawned.AmbientSound = default.AmbientSound;
|
||||
}
|
||||
for(i = 0; i < default.SkinRefs.Length;i ++){
|
||||
if(default.SkinRefs[i] != "" && (default.Skins.Length < i + 1 || default.Skins[i] == none))
|
||||
default.Skins[i] = Material(DynamicLoadObject(default.SkinRefs[i], class'Material'));
|
||||
if(Spawned != none)
|
||||
Spawned.Skins[i] = default.Skins[i];
|
||||
}
|
||||
}
|
||||
static function bool UnloadAssets(){
|
||||
local int i;
|
||||
UpdateDefaultMesh(none);
|
||||
default.AmbientSound = none;
|
||||
for(i = 0;i < default.Skins.Length;i ++)
|
||||
default.Skins[i] = none;
|
||||
return super.UnloadAssets();
|
||||
}
|
||||
simulated event ThirdPersonEffects(){
|
||||
local NicePlayerController PC;
|
||||
if((Level.NetMode == NM_DedicatedServer) || (Instigator == none))
|
||||
return;
|
||||
PC = NicePlayerController(Level.GetLocalPlayerController());
|
||||
if(FiringMode == 0){
|
||||
if(OldSpawnHitCount != SpawnHitCount){
|
||||
OldSpawnHitCount = SpawnHitCount;
|
||||
GetHitInfo();
|
||||
if(((Instigator != none) && (Instigator.Controller == PC)) || (VSize(PC.ViewTarget.Location - mHitLocation) < 4000)){
|
||||
if(PC != Instigator.Controller){
|
||||
if(mHitActor != none)
|
||||
Spawn(class'ROBulletHitEffect',,, mHitLocation, Rotator(-mHitNormal));
|
||||
CheckForSplash();
|
||||
SpawnTracer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(FlashCount > 0){
|
||||
if(KFPawn(Instigator) != none){
|
||||
if(FiringMode == 0)
|
||||
KFPawn(Instigator).StartFiringX(false, bRapidFire);
|
||||
else
|
||||
KFPawn(Instigator).StartFiringX(true, bRapidFire);
|
||||
}
|
||||
if(bDoFiringEffects && (!bSecondaryModeNoEffects || FiringMode == 0)){
|
||||
if((Level.TimeSeconds - LastRenderTime > 0.2) && (Instigator.Controller != PC))
|
||||
return;
|
||||
if(bSpawnLight)
|
||||
WeaponLight();
|
||||
DoFlashEmitter();
|
||||
ThirdPersonShellEject();
|
||||
}
|
||||
}
|
||||
else{
|
||||
GotoState('');
|
||||
if(KFPawn(Instigator) != none)
|
||||
KFPawn(Instigator).StopFiring();
|
||||
}
|
||||
}
|
||||
function UpdateHit(Actor HitActor, vector HitLocation, vector HitNormal){
|
||||
SpawnHitCount++;
|
||||
mHitLocation = HitLocation;
|
||||
mHitActor = HitActor;
|
||||
mHitNormal = HitNormal;
|
||||
NetUpdateTime = Level.TimeSeconds - 1;
|
||||
}
|
||||
simulated function ThirdPersonShellEject(){
|
||||
if((mShellCaseEmitter == none) && (Level.DetailMode != DM_Low) && !Level.bDropDetail){
|
||||
mShellCaseEmitter = Spawn(mShellCaseEmitterClass);
|
||||
if(mShellCaseEmitter != none)
|
||||
AttachToBone(mShellCaseEmitter, 'ShellPort');
|
||||
}
|
||||
if(mShellCaseEmitter != none)
|
||||
mShellCaseEmitter.mStartParticles++;
|
||||
}
|
||||
simulated function SpawnTracerAtLocation(vector HitLocation){
|
||||
local vector SpawnLoc, SpawnDir, SpawnVel;
|
||||
local float hitDist;
|
||||
if(!bDoFiringEffects)
|
||||
return;
|
||||
if(mTracer == none)
|
||||
mTracer = Spawn(mTracerClass);
|
||||
if(mTracer != none){
|
||||
SpawnLoc = GetTracerStart();
|
||||
mTracer.SetLocation(SpawnLoc);
|
||||
hitDist = VSize(HitLocation - SpawnLoc) - mTracerPullback;
|
||||
SpawnDir = Normal(HitLocation - SpawnLoc);
|
||||
if(hitDist > mTracerMinDistance){
|
||||
SpawnVel = SpawnDir * mTracerSpeed;
|
||||
mTracer.Emitters[0].StartVelocityRange.X.Min = SpawnVel.X;
|
||||
mTracer.Emitters[0].StartVelocityRange.X.Max = SpawnVel.X;
|
||||
mTracer.Emitters[0].StartVelocityRange.Y.Min = SpawnVel.Y;
|
||||
mTracer.Emitters[0].StartVelocityRange.Y.Max = SpawnVel.Y;
|
||||
mTracer.Emitters[0].StartVelocityRange.Z.Min = SpawnVel.Z;
|
||||
mTracer.Emitters[0].StartVelocityRange.Z.Max = SpawnVel.Z;
|
||||
|
||||
mTracer.Emitters[0].LifetimeRange.Min = hitDist / mTracerSpeed;
|
||||
mTracer.Emitters[0].LifetimeRange.Max = mTracer.Emitters[0].LifetimeRange.Min;
|
||||
|
||||
mTracer.SpawnParticle(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
simulated function CheckForSplashAtLocation(vector HitLoc){
|
||||
local Actor HitActor;
|
||||
local vector HitNormal, HitLocation;
|
||||
if(!Level.bDropDetail && (Level.DetailMode != DM_Low) && (SplashEffect != none) && !Instigator.PhysicsVolume.bWaterVolume){
|
||||
// check for splash
|
||||
bTraceWater = true;
|
||||
HitActor = Trace(HitLocation, HitNormal, HitLoc, Instigator.Location, true);
|
||||
bTraceWater = false;
|
||||
if((FluidSurfaceInfo(HitActor) != none) || ((PhysicsVolume(HitActor) != none) && PhysicsVolume(HitActor).bWaterVolume))
|
||||
Spawn(SplashEffect,,,HitLocation, rot(16384,0,0));
|
||||
}
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
bSpawnLight=True
|
||||
}
|
||||
11
kf_sources/NicePack/Classes/NiceAvoidMarker.uc
Normal file
11
kf_sources/NicePack/Classes/NiceAvoidMarker.uc
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
class NiceAvoidMarker extends AvoidMarker;
|
||||
function bool RelevantTo(Pawn P){
|
||||
local NiceZombieFleshpound niceFP;
|
||||
niceFP = NiceZombieFleshpound(P);
|
||||
if(niceFP != none && niceFP.IsInState('RageCharging'))
|
||||
return false;
|
||||
return super.RelevantTo(P);
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
}
|
||||
17
kf_sources/NicePack/Classes/NiceAvoidMarkerCarnage.uc
Normal file
17
kf_sources/NicePack/Classes/NiceAvoidMarkerCarnage.uc
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
class NiceAvoidMarkerCarnage extends NiceAvoidMarker;
|
||||
|
||||
var float healthLevel;
|
||||
|
||||
function bool RelevantTo(Pawn P){
|
||||
local NiceMonster niceZed;
|
||||
niceZed = NiceMonster(P);
|
||||
if (niceZed != none && niceZed.default.health <= healthLevel)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
lifespan = 2.5
|
||||
}
|
||||
11
kf_sources/NicePack/Classes/NiceAvoidMarkerExplosive.uc
Normal file
11
kf_sources/NicePack/Classes/NiceAvoidMarkerExplosive.uc
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
class NiceAvoidMarkerExplosive extends NiceAvoidMarker;
|
||||
function bool RelevantTo(Pawn P){
|
||||
local NiceMonster niceZed;
|
||||
niceZed = NiceMonster(P);
|
||||
if(niceZed != none && niceZed.default.Health >= 1000 && NiceZombieFleshpound(P) == none)
|
||||
return false;
|
||||
return super.RelevantTo(P);
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
}
|
||||
38
kf_sources/NicePack/Classes/NiceAvoidMarkerFP.uc
Normal file
38
kf_sources/NicePack/Classes/NiceAvoidMarkerFP.uc
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
class NiceAvoidMarkerFP extends NiceAvoidMarker;
|
||||
var NiceZombieFleshpound niceFP;
|
||||
state BigMeanAndScary
|
||||
{
|
||||
Begin:
|
||||
StartleBots();
|
||||
Sleep(1.0);
|
||||
GoTo('Begin');
|
||||
}
|
||||
function InitFor(NiceMonster V){
|
||||
if(V != none){
|
||||
niceFP = NiceZombieFleshpound(V);
|
||||
SetCollisionSize(niceFP.CollisionRadius * 3, niceFP.CollisionHeight + CollisionHeight);
|
||||
SetBase(niceFP);
|
||||
GoToState('BigMeanAndScary');
|
||||
}
|
||||
}
|
||||
function Touch( actor Other ){
|
||||
if((Pawn(Other) != none) && KFMonsterController(Pawn(Other).Controller) != none && RelevantTo(Pawn(Other)))
|
||||
KFMonsterController(Pawn(Other).Controller).AvoidThisMonster(niceFP);
|
||||
}
|
||||
function bool RelevantTo(Pawn P){
|
||||
local NiceMonster niceZed;
|
||||
niceZed = NiceMonster(P);
|
||||
if(niceZed != none && (niceZed.default.Health >= 1000 || NiceZombieJason(niceZed) != none))
|
||||
return false;
|
||||
return (niceFP != none && VSizeSquared(niceFP.Velocity) >= 75 && Super.RelevantTo(P) && niceFP.Velocity dot (P.Location - niceFP.Location) > 0 );
|
||||
}
|
||||
function StartleBots(){
|
||||
local KFMonster P;
|
||||
if(niceFP != none)
|
||||
ForEach CollidingActors(class'KFMonster', P, CollisionRadius)
|
||||
if(RelevantTo(P))
|
||||
KFMonsterController(P.Controller).AvoidThisMonster(niceFP);
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
}
|
||||
11
kf_sources/NicePack/Classes/NiceAvoidMarkerFlame.uc
Normal file
11
kf_sources/NicePack/Classes/NiceAvoidMarkerFlame.uc
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
class NiceAvoidMarkerFlame extends NiceAvoidMarker;
|
||||
function bool RelevantTo(Pawn P){
|
||||
local NiceMonster niceZed;
|
||||
niceZed = NiceMonster(P);
|
||||
if(niceZed != none && niceZed.bFireImmune)
|
||||
return false;
|
||||
return super.RelevantTo(P);
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
}
|
||||
29
kf_sources/NicePack/Classes/NiceAxe.uc
Normal file
29
kf_sources/NicePack/Classes/NiceAxe.uc
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
class NiceAxe extends NiceMeleeWeapon;
|
||||
defaultproperties
|
||||
{
|
||||
weaponRange=80.000000
|
||||
BloodSkinSwitchArray=0
|
||||
BloodyMaterialRef="KF_Weapons_Trip_T.melee.axe_bloody_cmb"
|
||||
bSpeedMeUp=True
|
||||
Weight=5.000000
|
||||
StandardDisplayFOV=75.000000
|
||||
TraderInfoTexture=Texture'KillingFloorHUD.Trader_Weapon_Images.Trader_Axe'
|
||||
bIsTier2Weapon=True
|
||||
MeshRef="KF_Weapons_Trip.Axe_Trip"
|
||||
SkinRefs(0)="KF_Weapons_Trip_T.melee.axe_cmb"
|
||||
SelectSoundRef="KF_AxeSnd.Axe_Select"
|
||||
HudImageRef="KillingFloorHUD.WeaponSelect.Axe_unselected"
|
||||
SelectedHudImageRef="KillingFloorHUD.WeaponSelect.Axe"
|
||||
FireModeClass(0)=class'NiceAxeFire'
|
||||
FireModeClass(1)=class'NiceAxeFireB'
|
||||
AIRating=0.300000
|
||||
Description="A common two-handed fireman's axe."
|
||||
DisplayFOV=75.000000
|
||||
Priority=55
|
||||
GroupOffset=3
|
||||
PickupClass=class'NiceAxePickup'
|
||||
BobDamping=8.000000
|
||||
AttachmentClass=class'NiceAxeAttachment'
|
||||
IconCoords=(X1=169,Y1=39,X2=241,Y2=77)
|
||||
ItemName="Axe"
|
||||
}
|
||||
45
kf_sources/NicePack/Classes/NiceAxeAttachment.uc
Normal file
45
kf_sources/NicePack/Classes/NiceAxeAttachment.uc
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
class NiceAxeAttachment extends NiceMeleeAttachment;
|
||||
defaultproperties
|
||||
{
|
||||
MovementAnims(0)="JogF_Axe"
|
||||
MovementAnims(1)="JogB_Axe"
|
||||
MovementAnims(2)="JogL_Axe"
|
||||
MovementAnims(3)="JogR_Axe"
|
||||
TurnLeftAnim="TurnL_Axe"
|
||||
TurnRightAnim="TurnR_Axe"
|
||||
CrouchAnims(0)="CHwalkF_Axe"
|
||||
CrouchAnims(1)="CHwalkB_Axe"
|
||||
CrouchAnims(2)="CHwalkL_Axe"
|
||||
CrouchAnims(3)="CHwalkR_Axe"
|
||||
CrouchTurnRightAnim="CH_TurnR_Axe"
|
||||
CrouchTurnLeftAnim="CH_TurnL_Axe"
|
||||
IdleCrouchAnim="CHIdle_Axe"
|
||||
IdleWeaponAnim="Idle_Axe"
|
||||
IdleRestAnim="Idle_Axe"
|
||||
IdleChatAnim="Idle_Axe"
|
||||
IdleHeavyAnim="Idle_Axe"
|
||||
IdleRifleAnim="Idle_Axe"
|
||||
FireAnims(0)="Attack1_Axe"
|
||||
FireAnims(1)="Attack2_Axe"
|
||||
FireAnims(2)="Attack3_Axe"
|
||||
FireAnims(3)="Attack3_Axe"
|
||||
FireAltAnims(0)="Attack1_Axe"
|
||||
FireAltAnims(1)="Attack2_Axe"
|
||||
FireAltAnims(2)="Attack3_Axe"
|
||||
FireAltAnims(3)="Attack3_Axe"
|
||||
FireCrouchAnims(0)="CHAttack1_Axe"
|
||||
FireCrouchAnims(1)="CHAttack2_Axe"
|
||||
FireCrouchAnims(2)="CHAttack3_Axe"
|
||||
FireCrouchAnims(3)="CHAttack3_Axe"
|
||||
FireCrouchAltAnims(0)="CHAttack1_Axe"
|
||||
FireCrouchAltAnims(1)="CHAttack2_Axe"
|
||||
FireCrouchAltAnims(2)="CHAttack3_Axe"
|
||||
FireCrouchAltAnims(3)="CHAttack3_Axe"
|
||||
HitAnims(0)="HitF_Axe"
|
||||
HitAnims(1)="HitB_Axe"
|
||||
HitAnims(2)="HitL_Axe"
|
||||
HitAnims(3)="HitR_Axe"
|
||||
PostFireBlendStandAnim="Blend_Axe"
|
||||
PostFireBlendCrouchAnim="CHBlend_Axe"
|
||||
MeshRef="KF_Weapons3rd_Trip.Axe_3rd"
|
||||
}
|
||||
18
kf_sources/NicePack/Classes/NiceAxeFire.uc
Normal file
18
kf_sources/NicePack/Classes/NiceAxeFire.uc
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
class NiceAxeFire extends NiceMeleeFire;
|
||||
defaultproperties
|
||||
{
|
||||
weaponRange=90.000000
|
||||
damageDelay=0.600000
|
||||
FireAnims(0)="Fire"
|
||||
FireAnims(1)="Fire2"
|
||||
FireAnims(2)="fire3"
|
||||
FireAnims(3)="Fire4"
|
||||
HitEffectClass=Class'KFMod.AxeHitEffect'
|
||||
MeleeHitSoundRefs(0)="KF_AxeSnd.Axe_HitFlesh"
|
||||
WideDamageMinHitAngle=0.750000
|
||||
DamageType=class'NiceDamTypeAxe'
|
||||
DamageMax=175
|
||||
FireAnimRate=0.893333
|
||||
FireRate=1.100000
|
||||
BotRefireRate=0.850000
|
||||
}
|
||||
14
kf_sources/NicePack/Classes/NiceAxeFireB.uc
Normal file
14
kf_sources/NicePack/Classes/NiceAxeFireB.uc
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
class NiceAxeFireB extends NiceMeleeFire;
|
||||
defaultproperties
|
||||
{
|
||||
weaponRange=90.000000
|
||||
damageDelay=0.760000
|
||||
FireAnims(0)="PowerAttack"
|
||||
HitEffectClass=Class'KFMod.AxeHitEffect'
|
||||
MeleeHitSoundRefs(0)="KF_AxeSnd.Axe_HitFlesh"
|
||||
DamageType=class'NiceDamTypeAxe'
|
||||
DamageMax=275
|
||||
bWaitForRelease=True
|
||||
FireRate=1.333000
|
||||
BotRefireRate=0.850000
|
||||
}
|
||||
21
kf_sources/NicePack/Classes/NiceAxePickup.uc
Normal file
21
kf_sources/NicePack/Classes/NiceAxePickup.uc
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
class NiceAxePickup extends NiceWeaponPickup;
|
||||
defaultproperties
|
||||
{
|
||||
Weight=5.000000
|
||||
cost=250
|
||||
PowerValue=56
|
||||
SpeedValue=32
|
||||
RangeValue=-20
|
||||
Description="A sturdy fireman's axe."
|
||||
ItemName="Axe"
|
||||
ItemShortName="Axe"
|
||||
CorrespondingPerkIndex=4
|
||||
VariantClasses(0)=Class'KFMod.GoldenKatanaPickup'
|
||||
InventoryType=class'NiceAxe'
|
||||
PickupMessage="You got the Fire Axe."
|
||||
PickupSound=Sound'KF_AxeSnd.Axe_Pickup'
|
||||
PickupForce="AssaultRiflePickup"
|
||||
StaticMesh=StaticMesh'KF_pickups_Trip.melee.Axe_Pickup'
|
||||
CollisionRadius=27.000000
|
||||
CollisionHeight=5.000000
|
||||
}
|
||||
38
kf_sources/NicePack/Classes/NiceBallisticHarpoon.uc
Normal file
38
kf_sources/NicePack/Classes/NiceBallisticHarpoon.uc
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
class NiceBallisticHarpoon extends NiceBullet;
|
||||
// Have we added this harpoon to a stuck projectiles list?
|
||||
var bool bAddedMyself;
|
||||
simulated function Tick(float delta){
|
||||
local NiceSealSquealHarpoonBomber harpoonWeap;
|
||||
if(bInitFinished && !bAddedMyself && bStuck && nicePlayer == localPlayer){
|
||||
bAddedMyself = true;
|
||||
harpoonWeap = NiceSealSquealHarpoonBomber(sourceWeapon);
|
||||
harpoonWeap.stuckProjectiles[harpoonWeap.stuckProjectiles.Length] = stuckID;
|
||||
}
|
||||
super.Tick(delta);
|
||||
}
|
||||
function KillBullet(){
|
||||
local int index;
|
||||
local NiceSealSquealHarpoonBomber harpoonWeap;
|
||||
if(bStuck && sourceWeapon != none){
|
||||
harpoonWeap = NiceSealSquealHarpoonBomber(sourceWeapon);
|
||||
for(index = 0;index < harpoonWeap.stuckProjectiles.Length;index ++)
|
||||
if(harpoonWeap.stuckProjectiles[index] == stuckID){
|
||||
NiceSealSquealHarpoonBomber(sourceWeapon).stuckProjectiles[index] = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
super.KillBullet();
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
charMinExplosionDist=300.000000
|
||||
bDisableComplexMovement=False
|
||||
movementFallTime=1.000000
|
||||
TrailClass=Class'KFMod.SealSquealFuseEmitter'
|
||||
trailXClass=None
|
||||
regularImpact=(noiseRef="KF_FY_SealSquealSND.WEP_Harpoon_Hit_Flesh")
|
||||
explosionImpact=(bImportanEffect=True,decalClass=Class'KFMod.KFScorchMark',EmitterClass=Class'KFMod.KFNadeLExplosion',emitterShiftWall=20.000000,emitterShiftPawn=20.000000,noiseRef="KF_FY_SealSquealSND.WEP_Harpoon_Explode",noiseVolume=2.000000)
|
||||
disintegrationImpact=(EmitterClass=Class'KFMod.SirenNadeDeflect',noiseRef="Inf_Weapons.faust_explode_distant02",noiseVolume=2.000000)
|
||||
StaticMeshRef="KF_IJC_Halloween_Weps2.Harpoon_Projectile"
|
||||
AmbientSoundRef="KF_IJC_HalloweenSnd.KF_FlarePistol_Projectile_Loop"
|
||||
}
|
||||
14
kf_sources/NicePack/Classes/NiceBallisticNade.uc
Normal file
14
kf_sources/NicePack/Classes/NiceBallisticNade.uc
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
class NiceBallisticNade extends NiceBullet;
|
||||
defaultproperties
|
||||
{
|
||||
charMinExplosionDist=250.000000
|
||||
bDisableComplexMovement=False
|
||||
movementAcceleration=(Z=-490.000000)
|
||||
movementFallTime=1.000000
|
||||
TrailClass=Class'ROEffects.PanzerfaustTrail'
|
||||
trailXClass=None
|
||||
explosionImpact=(bImportanEffect=True,decalClass=Class'KFMod.KFScorchMark',EmitterClass=Class'KFMod.KFNadeLExplosion',emitterShiftWall=20.000000,emitterShiftPawn=20.000000,noiseRef="KF_GrenadeSnd.Nade_Explode_1",noiseVolume=2.000000)
|
||||
disintegrationImpact=(EmitterClass=Class'KFMod.SirenNadeDeflect',noiseRef="Inf_Weapons.faust_explode_distant02",noiseVolume=2.000000)
|
||||
StaticMeshRef="kf_generic_sm.40mm_Warhead"
|
||||
DrawScale=3.000000
|
||||
}
|
||||
11
kf_sources/NicePack/Classes/NiceBenelliAmmo.uc
Normal file
11
kf_sources/NicePack/Classes/NiceBenelliAmmo.uc
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
class NiceBenelliAmmo extends NiceAmmo;
|
||||
defaultproperties
|
||||
{
|
||||
WeaponPickupClass=class'NiceBenelliPickup'
|
||||
AmmoPickupAmount=6
|
||||
MaxAmmo=60
|
||||
InitialAmount=15
|
||||
PickupClass=class'NiceBenelliAmmoPickup'
|
||||
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
|
||||
IconCoords=(X1=451,Y1=445,X2=510,Y2=500)
|
||||
}
|
||||
8
kf_sources/NicePack/Classes/NiceBenelliAmmoPickup.uc
Normal file
8
kf_sources/NicePack/Classes/NiceBenelliAmmoPickup.uc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
class NiceBenelliAmmoPickup extends NiceAmmoPickup;
|
||||
defaultproperties
|
||||
{
|
||||
AmmoAmount=6
|
||||
InventoryType=class'NiceBenelliAmmo'
|
||||
PickupMessage="12-Gauge Shells"
|
||||
StaticMesh=None
|
||||
}
|
||||
21
kf_sources/NicePack/Classes/NiceBenelliAttachment.uc
Normal file
21
kf_sources/NicePack/Classes/NiceBenelliAttachment.uc
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
class NiceBenelliAttachment extends NiceShotgunAttachment;
|
||||
defaultproperties
|
||||
{
|
||||
FireAnims(0)="Fire_Benelli"
|
||||
FireAnims(1)="Fire_Benelli"
|
||||
FireAnims(2)="Fire_Benelli"
|
||||
FireAnims(3)="Fire_Benelli"
|
||||
FireAltAnims(0)="Fire_Benelli"
|
||||
FireAltAnims(1)="Fire_Benelli"
|
||||
FireAltAnims(2)="Fire_Benelli"
|
||||
FireAltAnims(3)="Fire_Benelli"
|
||||
FireCrouchAnims(0)="CHFire_Benelli"
|
||||
FireCrouchAnims(1)="CHFire_Benelli"
|
||||
FireCrouchAnims(2)="CHFire_Benelli"
|
||||
FireCrouchAnims(3)="CHFire_Benelli"
|
||||
FireCrouchAltAnims(0)="CHFire_Benelli"
|
||||
FireCrouchAltAnims(1)="CHFire_Benelli"
|
||||
FireCrouchAltAnims(2)="CHFire_Benelli"
|
||||
FireCrouchAltAnims(3)="CHFire_Benelli"
|
||||
MeshRef="KF_Weapons3rd3_Trip.Benelli_3rd"
|
||||
}
|
||||
14
kf_sources/NicePack/Classes/NiceBenelliFire.uc
Normal file
14
kf_sources/NicePack/Classes/NiceBenelliFire.uc
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
class NiceBenelliFire extends NiceShotgunFire;
|
||||
defaultproperties
|
||||
{
|
||||
KickMomentum=(X=-45.000000,Z=10.000000)
|
||||
ShellEjectClass=Class'ROEffects.KFShellEjectBenelli'
|
||||
ShellEjectBoneName="Shell_eject"
|
||||
DamageType=class'NiceDamTypeBenelli'
|
||||
FireAnimRate=1.000000
|
||||
FireRate=0.200000
|
||||
DamageMax=63
|
||||
AmmoClass=class'NiceBenelliAmmo'
|
||||
Spread=1125.000000
|
||||
BotRefireRate=0.200000
|
||||
}
|
||||
25
kf_sources/NicePack/Classes/NiceBenelliPickup.uc
Normal file
25
kf_sources/NicePack/Classes/NiceBenelliPickup.uc
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
class NiceBenelliPickup extends NiceWeaponPickup;
|
||||
defaultproperties
|
||||
{
|
||||
Weight=8.000000
|
||||
cost=500
|
||||
AmmoCost=13
|
||||
BuyClipSize=6
|
||||
PowerValue=70
|
||||
SpeedValue=60
|
||||
RangeValue=15
|
||||
Description="A military tactical shotgun with semi automatic fire capability. Holds up to 6 shells. "
|
||||
ItemName="Benelli shotgun"
|
||||
ItemShortName="Benelli shotgun"
|
||||
AmmoItemName="12-gauge shells"
|
||||
CorrespondingPerkIndex=1
|
||||
EquipmentCategoryID=2
|
||||
VariantClasses(0)=Class'KFMod.GoldenBenelliPickup'
|
||||
InventoryType=class'NiceBenelliShotgun'
|
||||
PickupMessage="You got the Benelli shotgun"
|
||||
PickupSound=Sound'KF_M4ShotgunSnd.foley.WEP_Benelli_Foley_Pickup'
|
||||
PickupForce="AssaultRiflePickup"
|
||||
StaticMesh=StaticMesh'KF_pickups3_Trip.Rifles.Benelli_Pickup'
|
||||
CollisionRadius=35.000000
|
||||
CollisionHeight=5.000000
|
||||
}
|
||||
52
kf_sources/NicePack/Classes/NiceBenelliShotgun.uc
Normal file
52
kf_sources/NicePack/Classes/NiceBenelliShotgun.uc
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
class NiceBenelliShotgun extends NiceWeapon;
|
||||
simulated function fillSubReloadStages(){
|
||||
// Loading 6 shells during 174 frames tops, with first shell loaded at frame 22, with 24 frames between load moments
|
||||
generateReloadStages(6, 174, 22, 24);
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
bChangeClipIcon=True
|
||||
hudClipTexture=Texture'KillingFloorHUD.HUD.Hud_Single_Bullet'
|
||||
reloadType=RTYPE_SINGLE
|
||||
FirstPersonFlashlightOffset=(X=-25.000000,Y=-18.000000,Z=8.000000)
|
||||
MagCapacity=6
|
||||
ReloadRate=0.750000
|
||||
ReloadAnim="Reload"
|
||||
ReloadAnimRate=1.200000
|
||||
bHoldToReload=True
|
||||
WeaponReloadAnim="Reload_Shotgun"
|
||||
Weight=5.000000
|
||||
bTorchEnabled=True
|
||||
bHasAimingMode=True
|
||||
IdleAimAnim="Idle_Iron"
|
||||
StandardDisplayFOV=65.000000
|
||||
SleeveNum=2
|
||||
TraderInfoTexture=Texture'KillingFloor2HUD.Trader_Weapon_Icons.Trader_Beneli'
|
||||
bIsTier2Weapon=True
|
||||
MeshRef="KF_Wep_Benelli.Benelli_Trip"
|
||||
SkinRefs(0)="KF_Weapons4_Trip_T.Weapons.Benelli_M4_cmb"
|
||||
SkinRefs(1)="KF_Weapons2_Trip_T.Special.Aimpoint_sight_shdr"
|
||||
SelectSoundRef="KF_M4ShotgunSnd.WEP_Benelli_Foley_Select"
|
||||
HudImageRef="KillingFloor2HUD.WeaponSelect.Beneli_unselected"
|
||||
SelectedHudImageRef="KillingFloor2HUD.WeaponSelect.Beneli"
|
||||
PlayerIronSightFOV=70.000000
|
||||
ZoomedDisplayFOV=40.000000
|
||||
FireModeClass(0)=class'NiceBenelliFire'
|
||||
FireModeClass(1)=Class'KFMod.NoFire'
|
||||
PutDownAnim="PutDown"
|
||||
AIRating=0.600000
|
||||
CurrentRating=0.600000
|
||||
bShowChargingBar=True
|
||||
Description="A military tactical shotgun with semi automatic fire capability. Holds up to 6 shells. "
|
||||
DisplayFOV=65.000000
|
||||
Priority=170
|
||||
InventoryGroup=3
|
||||
GroupOffset=9
|
||||
PickupClass=class'NiceBenelliPickup'
|
||||
PlayerViewOffset=(X=20.000000,Y=18.750000,Z=-7.500000)
|
||||
BobDamping=7.000000
|
||||
AttachmentClass=class'NiceBenelliAttachment'
|
||||
IconCoords=(X1=169,Y1=172,X2=245,Y2=208)
|
||||
ItemName="Benelli shotgun"
|
||||
TransientSoundVolume=1.000000
|
||||
}
|
||||
8
kf_sources/NicePack/Classes/NiceBlockHitEmitter.uc
Normal file
8
kf_sources/NicePack/Classes/NiceBlockHitEmitter.uc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
class NiceBlockHitEmitter extends MetalHitEmitter;
|
||||
defaultproperties
|
||||
{
|
||||
ImpactSounds(0)=None
|
||||
ImpactSounds(1)=None
|
||||
ImpactSounds(2)=None
|
||||
RemoteRole=ROLE_SimulatedProxy
|
||||
}
|
||||
9
kf_sources/NicePack/Classes/NiceBlowerThrower.uc
Normal file
9
kf_sources/NicePack/Classes/NiceBlowerThrower.uc
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
class NiceBlowerThrower extends BlowerThrower;
|
||||
defaultproperties
|
||||
{
|
||||
AppID=0
|
||||
FireModeClass(0)=class'NiceBlowerThrowerFire'
|
||||
FireModeClass(1)=class'NiceBlowerThrowerAltFire'
|
||||
PickupClass=class'NiceBlowerThrowerPickup'
|
||||
ItemName="BlowerThrower NW"
|
||||
}
|
||||
5
kf_sources/NicePack/Classes/NiceBlowerThrowerAltFire.uc
Normal file
5
kf_sources/NicePack/Classes/NiceBlowerThrowerAltFire.uc
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class NiceBlowerThrowerAltFire extends BlowerThrowerAltFire;
|
||||
defaultproperties
|
||||
{
|
||||
AmmoClass=class'NiceBlowerThrowerAmmo'
|
||||
}
|
||||
7
kf_sources/NicePack/Classes/NiceBlowerThrowerAmmo.uc
Normal file
7
kf_sources/NicePack/Classes/NiceBlowerThrowerAmmo.uc
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
class NiceBlowerThrowerAmmo extends BlowerThrowerAmmo;
|
||||
#EXEC OBJ LOAD FILE=KillingFloorHUD.utx
|
||||
defaultproperties
|
||||
{
|
||||
MaxAmmo=400
|
||||
PickupClass=class'NiceBlowerThrowerAmmoPickup'
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class NiceBlowerThrowerAmmoPickup extends BlowerThrowerAmmoPickup;
|
||||
defaultproperties
|
||||
{
|
||||
InventoryType=class'NiceBlowerThrowerAmmo'
|
||||
}
|
||||
5
kf_sources/NicePack/Classes/NiceBlowerThrowerFire.uc
Normal file
5
kf_sources/NicePack/Classes/NiceBlowerThrowerFire.uc
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class NiceBlowerThrowerFire extends BlowerThrowerFire;
|
||||
defaultproperties
|
||||
{
|
||||
AmmoClass=class'NiceBlowerThrowerAmmo'
|
||||
}
|
||||
8
kf_sources/NicePack/Classes/NiceBlowerThrowerPickup.uc
Normal file
8
kf_sources/NicePack/Classes/NiceBlowerThrowerPickup.uc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
class NiceBlowerThrowerPickup extends BlowerThrowerPickup;
|
||||
defaultproperties
|
||||
{
|
||||
ItemName="Blower Thrower Bile Launcher NW"
|
||||
ItemShortName="Blower Thrower NW"
|
||||
InventoryType=class'NiceBlowerThrower'
|
||||
PickupMessage="You got the BlowerThrower NW"
|
||||
}
|
||||
103
kf_sources/NicePack/Classes/NiceBoomStick.uc
Normal file
103
kf_sources/NicePack/Classes/NiceBoomStick.uc
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
class NiceBoomStick extends NiceWeapon;
|
||||
#EXEC OBJ LOAD FILE=KillingFloorHUD.utx
|
||||
var float glueTiming;
|
||||
var float firstShellTiming, secondShellTiming, jumpTiming;
|
||||
var const string firstShellStr, secondShellStr, jumpStr;
|
||||
simulated function PostBeginPlay(){
|
||||
local EventRecord record;
|
||||
local AutoReloadAnimDesc reloadDesc;
|
||||
// Setup animation timings
|
||||
autoReloadsDescriptions.Length = 0;
|
||||
reloadDesc.canInterruptFrame = 0.056;
|
||||
reloadDesc.trashStartFrame = secondShellTiming;
|
||||
reloadDesc.resumeFrame = 0.056;
|
||||
reloadDesc.speedFrame = 0.056;
|
||||
// Setup all possible fire animations
|
||||
reloadDesc.animName = 'Fire_Both';
|
||||
autoReloadsDescriptions[0] = reloadDesc;
|
||||
reloadDesc.animName = 'Fire_Both_Iron';
|
||||
autoReloadsDescriptions[1] = reloadDesc;
|
||||
reloadDesc.animName = 'Fire_Last';
|
||||
autoReloadsDescriptions[2] = reloadDesc;
|
||||
reloadDesc.animName = 'Fire_Last_Iron';
|
||||
autoReloadsDescriptions[3] = reloadDesc;
|
||||
// Setup reload events
|
||||
record.eventName = jumpStr;
|
||||
record.eventFrame = jumpTiming;
|
||||
relEvents[relEvents.Length] = record;
|
||||
record.eventName = firstShellStr;
|
||||
record.eventFrame = firstShellTiming;
|
||||
relEvents[relEvents.Length] = record;
|
||||
record.eventName = secondShellStr;
|
||||
record.eventFrame = secondShellTiming;
|
||||
relEvents[relEvents.Length] = record;
|
||||
super.PostBeginPlay();
|
||||
}
|
||||
simulated function ReloadEvent(string eventName){
|
||||
if(eventName ~= jumpStr && GetMagazineAmmo() > 0)
|
||||
SetAnimFrame(glueTiming);
|
||||
if(eventName ~= firstShellStr)
|
||||
MagAmmoRemainingClient = Min(1, AmmoAmount(0));
|
||||
else if(eventName ~= secondShellStr)
|
||||
MagAmmoRemainingClient = Min(2, AmmoAmount(0));
|
||||
ServerSetMagSize(MagAmmoRemainingClient, bRoundInChamber, Level.TimeSeconds);
|
||||
}
|
||||
simulated function AddAutoReloadedAmmo(){
|
||||
MagAmmoRemainingClient = Min(2, AmmoAmount(0));
|
||||
ServerSetMagSize(MagAmmoRemainingClient, bRoundInChamber, Level.TimeSeconds);
|
||||
}
|
||||
simulated function bool AltFireCanForceInterruptReload(){
|
||||
return (GetMagazineAmmo() > 0);
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
glueTiming=0.633330
|
||||
firstShellTiming=0.555550
|
||||
secondShellTiming=0.733330
|
||||
jumpTiming=0.388880
|
||||
firstShellStr="firstShell"
|
||||
secondShellStr="secondShellStr"
|
||||
jumpStr="jumpStr"
|
||||
bChangeClipIcon=True
|
||||
hudClipTexture=Texture'KillingFloorHUD.HUD.Hud_Single_Bullet'
|
||||
reloadType=RTYPE_AUTO
|
||||
ForceZoomOutOnFireTime=0.010000
|
||||
ForceZoomOutOnAltFireTime=0.010000
|
||||
MagCapacity=2
|
||||
Weight=6.000000
|
||||
ReloadRate=2.250000
|
||||
ReloadAnim="Reload"
|
||||
ReloadAnimRate=1.100000
|
||||
bHoldToReload=True
|
||||
WeaponReloadAnim="Reload_HuntingShotgun"
|
||||
bHasAimingMode=True
|
||||
IdleAimAnim="Idle_Iron"
|
||||
StandardDisplayFOV=55.000000
|
||||
TraderInfoTexture=Texture'KillingFloorHUD.Trader_Weapon_Images.Trader_Hunting_Shotgun'
|
||||
bIsTier2Weapon=True
|
||||
MeshRef="KF_Weapons_Trip.BoomStick_Trip"
|
||||
SkinRefs(0)="KF_Weapons_Trip_T.Shotguns.boomstick_cmb"
|
||||
SelectSoundRef="KF_DoubleSGSnd.2Barrel_Select"
|
||||
HudImageRef="KillingFloorHUD.WeaponSelect.BoomStic_unselected"
|
||||
SelectedHudImageRef="KillingFloorHUD.WeaponSelect.BoomStick"
|
||||
PlayerIronSightFOV=70.000000
|
||||
ZoomedDisplayFOV=40.000000
|
||||
FireModeClass(0)=class'NiceBoomStickAltFire'
|
||||
FireModeClass(1)=class'NiceBoomStickFire'
|
||||
PutDownAnim="PutDown"
|
||||
AIRating=0.900000
|
||||
CurrentRating=0.900000
|
||||
bSniping=False
|
||||
Description="A double barreled shotgun used by big game hunters. It fires two slugs simultaneously and can bring down even the largest targets, quickly."
|
||||
DisplayFOV=55.000000
|
||||
Priority=160
|
||||
InventoryGroup=4
|
||||
GroupOffset=2
|
||||
PickupClass=class'NiceBoomStickPickup'
|
||||
PlayerViewOffset=(X=8.000000,Y=14.000000,Z=-8.000000)
|
||||
BobDamping=6.000000
|
||||
AttachmentClass=class'NiceBoomStickAttachment'
|
||||
ItemName="Hunting Shotgun"
|
||||
bUseDynamicLights=True
|
||||
TransientSoundVolume=1.000000
|
||||
}
|
||||
26
kf_sources/NicePack/Classes/NiceBoomStickAltFire.uc
Normal file
26
kf_sources/NicePack/Classes/NiceBoomStickAltFire.uc
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
class NiceBoomStickAltFire extends NiceBoomStickFire;
|
||||
// Overload to force last shot to have a different animation with reload
|
||||
// NICETODO: uncomment this
|
||||
function name GetCorrectAnim(bool bLoop, bool bAimed) {
|
||||
if(currentContext.sourceWeapon != none && currentContext.sourceWeapon.MagAmmoRemainingClient > 0)
|
||||
return super.GetCorrectAnim(bLoop, bAimed);
|
||||
if(bAimed)
|
||||
return 'Fire_Last_Iron';
|
||||
else
|
||||
return 'Fire_Last';
|
||||
return FireAnim;
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
KickMomentum=(X=-50.000000,Z=22.000000)
|
||||
FireAimedAnim="Fire_Iron"
|
||||
maxVerticalRecoilAngle=1500
|
||||
FireSoundRef="KF_DoubleSGSnd.2Barrel_Fire"
|
||||
StereoFireSoundRef="KF_DoubleSGSnd.2Barrel_FireST"
|
||||
TransientSoundVolume=1.800000
|
||||
FireAnim="Fire"
|
||||
AmmoPerFire=1
|
||||
ShakeRotMag=(X=50.000000,Y=50.000000,Z=400.000000)
|
||||
ShakeRotTime=5.000000
|
||||
ShakeOffsetTime=3.000000
|
||||
}
|
||||
51
kf_sources/NicePack/Classes/NiceBoomStickAttachment.uc
Normal file
51
kf_sources/NicePack/Classes/NiceBoomStickAttachment.uc
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
class NiceBoomStickAttachment extends NiceAttachment;
|
||||
defaultproperties
|
||||
{
|
||||
mMuzFlashClass=Class'ROEffects.MuzzleFlash3rdKar'
|
||||
mShellCaseEmitterClass=Class'KFMod.KFShotgunShellSpewer'
|
||||
MovementAnims(0)="JogF_HuntingShotgun"
|
||||
MovementAnims(1)="JogB_HuntingShotgun"
|
||||
MovementAnims(2)="JogL_HuntingShotgun"
|
||||
MovementAnims(3)="JogR_HuntingShotgun"
|
||||
TurnLeftAnim="TurnL_HuntingShotgun"
|
||||
TurnRightAnim="TurnR_HuntingShotgun"
|
||||
CrouchAnims(0)="CHwalkF_HuntingShotgun"
|
||||
CrouchAnims(1)="CHwalkB_HuntingShotgun"
|
||||
CrouchAnims(2)="CHwalkL_HuntingShotgun"
|
||||
CrouchAnims(3)="CHwalkR_HuntingShotgun"
|
||||
WalkAnims(0)="WalkF_HuntingShotgun"
|
||||
WalkAnims(1)="WalkB_HuntingShotgun"
|
||||
WalkAnims(2)="WalkL_HuntingShotgun"
|
||||
WalkAnims(3)="WalkR_HuntingShotgun"
|
||||
CrouchTurnRightAnim="CH_TurnR_HuntingShotgun"
|
||||
CrouchTurnLeftAnim="CH_TurnL_HuntingShotgun"
|
||||
IdleCrouchAnim="CHIdle_HuntingShotgun"
|
||||
IdleWeaponAnim="Idle_HuntingShotgun"
|
||||
IdleRestAnim="Idle_HuntingShotgun"
|
||||
IdleChatAnim="Idle_HuntingShotgun"
|
||||
IdleHeavyAnim="Idle_HuntingShotgun"
|
||||
IdleRifleAnim="Idle_HuntingShotgun"
|
||||
FireAnims(0)="Fire_HuntingShotgun"
|
||||
FireAnims(1)="Fire_HuntingShotgun"
|
||||
FireAnims(2)="Fire_HuntingShotgun"
|
||||
FireAnims(3)="Fire_HuntingShotgun"
|
||||
FireAltAnims(0)="Fire_HuntingShotgun"
|
||||
FireAltAnims(1)="Fire_HuntingShotgun"
|
||||
FireAltAnims(2)="Fire_HuntingShotgun"
|
||||
FireAltAnims(3)="Fire_HuntingShotgun"
|
||||
FireCrouchAnims(0)="CHFire_HuntingShotgun"
|
||||
FireCrouchAnims(1)="CHFire_HuntingShotgun"
|
||||
FireCrouchAnims(2)="CHFire_HuntingShotgun"
|
||||
FireCrouchAnims(3)="CHFire_HuntingShotgun"
|
||||
FireCrouchAltAnims(0)="CHFire_HuntingShotgun"
|
||||
FireCrouchAltAnims(1)="CHFire_HuntingShotgun"
|
||||
FireCrouchAltAnims(2)="CHFire_HuntingShotgun"
|
||||
FireCrouchAltAnims(3)="CHFire_HuntingShotgun"
|
||||
HitAnims(0)="HitF_HuntingShotgun"
|
||||
HitAnims(1)="HitB_HuntingShotgun"
|
||||
HitAnims(2)="HitL_HuntingShotgun"
|
||||
HitAnims(3)="HitR_HuntingShotgun"
|
||||
PostFireBlendStandAnim="Blend_HuntingShotgun"
|
||||
PostFireBlendCrouchAnim="CHBlend_HuntingShotgun"
|
||||
MeshRef="KF_Weapons3rd_Trip.HuntingShot_3rd"
|
||||
}
|
||||
63
kf_sources/NicePack/Classes/NiceBoomStickFire.uc
Normal file
63
kf_sources/NicePack/Classes/NiceBoomStickFire.uc
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
class NiceBoomStickFire extends NiceShotgunFire;
|
||||
var Emitter Flash2Emitter;
|
||||
var name MuzzleBoneLeft;
|
||||
var name MuzzleBoneRight;
|
||||
simulated function InitEffects(){
|
||||
if((Level.NetMode == NM_DedicatedServer) || (AIController(Instigator.Controller) != none))
|
||||
return;
|
||||
if((FlashEmitterClass != none) && ((FlashEmitter == none) || FlashEmitter.bDeleteMe)){
|
||||
FlashEmitter = Weapon.Spawn(FlashEmitterClass);
|
||||
Weapon.AttachToBone(FlashEmitter, MuzzleBoneLeft);
|
||||
}
|
||||
if((FlashEmitterClass != none) && ((Flash2Emitter == none) || Flash2Emitter.bDeleteMe)){
|
||||
Flash2Emitter = Weapon.Spawn(FlashEmitterClass);
|
||||
Weapon.AttachToBone(Flash2Emitter, MuzzleBoneRight);
|
||||
}
|
||||
if((SmokeEmitterClass != none) && ((SmokeEmitter == none) || SmokeEmitter.bDeleteMe))
|
||||
SmokeEmitter = Weapon.Spawn(SmokeEmitterClass);
|
||||
}
|
||||
simulated function DestroyEffects(){
|
||||
super.DestroyEffects();
|
||||
if(Flash2Emitter != none)
|
||||
Flash2Emitter.Destroy();
|
||||
}//MEANTODO
|
||||
function FlashMuzzleFlash(){
|
||||
if(currentContext.sourceWeapon == none)
|
||||
return;
|
||||
if(currentContext.sourceWeapon.MagAmmoRemainingClient == 2){
|
||||
if(Flash2Emitter != none)
|
||||
Flash2Emitter.Trigger(Weapon, Instigator);
|
||||
}
|
||||
else if(FlashEmitter != none)
|
||||
FlashEmitter.Trigger(Weapon, Instigator);
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
MuzzleBoneLeft="Tip_Left"
|
||||
MuzzleBoneRight="Tip_Right"
|
||||
FireIncompleteAnim="Fire_Last"
|
||||
FireIncompleteAimedAnim="Fire_Last_Iron"
|
||||
bCanFireIncomplete=True
|
||||
ProjPerFire=10
|
||||
KickMomentum=(X=-105.000000,Z=55.000000)
|
||||
FireAimedAnim="Fire_Both_Iron"
|
||||
RecoilRate=0.070000
|
||||
maxVerticalRecoilAngle=3200
|
||||
FireSoundRef="KF_DoubleSGSnd.2Barrel_Fire_Dual"
|
||||
StereoFireSoundRef="KF_DoubleSGSnd.2Barrel_Fire_DualST"
|
||||
NoAmmoSoundRef="KF_DoubleSGSnd.2Barrel_DryFire"
|
||||
DamageType=class'NiceDamTypeDBShotgun'
|
||||
DamageMax=63
|
||||
TransientSoundVolume=1.900000
|
||||
FireAnim="Fire_Both"
|
||||
FireRate=0.000000
|
||||
AmmoClass=class'NiceDBShotgunAmmo'
|
||||
AmmoPerFire=2
|
||||
ShakeRotMag=(X=75.000000,Y=75.000000,Z=600.000000)
|
||||
ShakeRotTime=6.000000
|
||||
ShakeOffsetTime=3.500000
|
||||
BotRefireRate=2.500000
|
||||
aimerror=2.000000
|
||||
Spread=2000.000000
|
||||
FireAnimRate=1.25
|
||||
}
|
||||
24
kf_sources/NicePack/Classes/NiceBoomStickPickup.uc
Normal file
24
kf_sources/NicePack/Classes/NiceBoomStickPickup.uc
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
class NiceBoomStickPickup extends NiceWeaponPickup;
|
||||
var int SingleShotCount;
|
||||
defaultproperties
|
||||
{
|
||||
cost=750
|
||||
AmmoCost=5
|
||||
BuyClipSize=2
|
||||
PowerValue=90
|
||||
SpeedValue=30
|
||||
RangeValue=12
|
||||
Description="A double barreled shotgun used by big game hunters."
|
||||
ItemName="Hunting Shotgun"
|
||||
ItemShortName="Hunting Shotgun"
|
||||
AmmoItemName="12-gauge Hunting shells"
|
||||
CorrespondingPerkIndex=1
|
||||
EquipmentCategoryID=3
|
||||
InventoryType=class'NiceBoomStick'
|
||||
PickupMessage="You got the Hunting Shotgun"
|
||||
PickupSound=Sound'KF_DoubleSGSnd.2Barrel_Pickup'
|
||||
PickupForce="AssaultRiflePickup"
|
||||
StaticMesh=StaticMesh'KF_pickups_Trip.Shotgun.boomstick_pickup'
|
||||
CollisionRadius=35.000000
|
||||
CollisionHeight=5.000000
|
||||
}
|
||||
90
kf_sources/NicePack/Classes/NiceBossHPNeedle.uc
Normal file
90
kf_sources/NicePack/Classes/NiceBossHPNeedle.uc
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
class NiceBossHPNeedle extends Decoration
|
||||
NotPlaceable;
|
||||
#exec obj load file="NewPatchSM.usx"
|
||||
simulated function DroppedNow()
|
||||
{
|
||||
SetCollision(True);
|
||||
SetPhysics(PHYS_Falling);
|
||||
bFixedRotationDir = True;
|
||||
RotationRate = RotRand(True);
|
||||
}
|
||||
simulated function HitWall( vector HitNormal, actor HitWall )
|
||||
{
|
||||
local rotator R;
|
||||
if( VSize(Velocity)<40 )
|
||||
{
|
||||
SetPhysics(PHYS_none);
|
||||
R.Roll = Rand(65536);
|
||||
R.Yaw = Rand(65536);
|
||||
SetRotation(R);
|
||||
Return;
|
||||
}
|
||||
Velocity = MirrorVectorByNormal(Velocity,HitNormal)*0.75;
|
||||
if( HitWall!=none && HitWall.Physics!=PHYS_none )
|
||||
Velocity+=HitWall.Velocity;
|
||||
}
|
||||
simulated function Landed( vector HitNormal )
|
||||
{
|
||||
HitWall(HitNormal,none);
|
||||
}
|
||||
function TakeDamage( int NDamage, Pawn instigatedBy, Vector hitlocation,
|
||||
Vector momentum, class<DamageType> damageType, optional int HitIndex)
|
||||
{
|
||||
if( Physics==PHYS_none )
|
||||
{
|
||||
SetPhysics(PHYS_Falling);
|
||||
bFixedRotationDir = True;
|
||||
RotationRate = RotRand(True);
|
||||
Velocity = vect(0,0,0);
|
||||
}
|
||||
Velocity+=momentum/10;
|
||||
}
|
||||
simulated function Destroyed();
|
||||
function Bump( actor Other );
|
||||
singular function PhysicsVolumeChange( PhysicsVolume NewVolume );
|
||||
// Overriden so it doesn't damage the patriarch when he drops a needle!
|
||||
singular function BaseChange()
|
||||
{
|
||||
if( Velocity.Z < -500 )
|
||||
TakeDamage( (1-Velocity.Z/30),Instigator,Location,vect(0,0,0) , class'Crushed');
|
||||
if( base == none )
|
||||
{
|
||||
if ( !bInterpolating && bPushable && (Physics == PHYS_none) )
|
||||
SetPhysics(PHYS_Falling);
|
||||
}
|
||||
else if( Pawn(Base) != none )
|
||||
{
|
||||
//Base.TakeDamage( (1-Velocity.Z/400)* mass/Base.Mass,Instigator,Location,0.5 * Velocity , class'Crushed');
|
||||
Velocity.Z = 100;
|
||||
if (FRand() < 0.5)
|
||||
Velocity.X += 70;
|
||||
else
|
||||
Velocity.Y += 70;
|
||||
SetPhysics(PHYS_Falling);
|
||||
}
|
||||
else if( Decoration(Base)!=none && Velocity.Z<-500 )
|
||||
{
|
||||
Base.TakeDamage((1 - Mass/Base.Mass * Velocity.Z/30), Instigator, Location, 0.2 * Velocity, class'Crushed');
|
||||
Velocity.Z = 100;
|
||||
if (FRand() < 0.5)
|
||||
Velocity.X += 70;
|
||||
else
|
||||
Velocity.Y += 70;
|
||||
SetPhysics(PHYS_Falling);
|
||||
}
|
||||
else
|
||||
instigator = none;
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
DrawType=DT_StaticMesh
|
||||
StaticMesh=StaticMesh'NewPatchSM.BossSyringe'
|
||||
bStatic=False
|
||||
RemoteRole=ROLE_None
|
||||
LifeSpan=300.000000
|
||||
CollisionRadius=4.000000
|
||||
CollisionHeight=4.000000
|
||||
bCollideWorld=True
|
||||
bProjTarget=True
|
||||
bBounce=True
|
||||
}
|
||||
21
kf_sources/NicePack/Classes/NiceBossLAWProj.uc
Normal file
21
kf_sources/NicePack/Classes/NiceBossLAWProj.uc
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
class NiceBossLAWProj extends LAWProj;
|
||||
//-----------------------------------------------------------------------------
|
||||
// PostBeginPlay
|
||||
//-----------------------------------------------------------------------------
|
||||
simulated function PostBeginPlay()
|
||||
{
|
||||
// Difficulty Scaling
|
||||
if(Level.Game != none){
|
||||
if(Level.Game.GameDifficulty >= 5.0) // Hell on Earth & Suicidal
|
||||
damage = default.damage * 1.3;
|
||||
else
|
||||
damage = default.damage * 1.0;
|
||||
}
|
||||
super.PostBeginPlay();
|
||||
}
|
||||
defaultproperties
|
||||
{
|
||||
ArmDistSquared=0.000000
|
||||
Damage=200.000000
|
||||
MyDamageType=Class'KFMod.DamTypeFrag'
|
||||
}
|
||||
1017
kf_sources/NicePack/Classes/NiceBullet.uc
Normal file
1017
kf_sources/NicePack/Classes/NiceBullet.uc
Normal file
File diff suppressed because it is too large
Load diff
331
kf_sources/NicePack/Classes/NiceBulletAdapter.uc
Normal file
331
kf_sources/NicePack/Classes/NiceBulletAdapter.uc
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
//======================================================================================================================
|
||||
// NicePack / NiceBulletAdapter
|
||||
//======================================================================================================================
|
||||
// Temporary stand-in for future functionality.
|
||||
//======================================================================================================================
|
||||
// 'Nice pack' source
|
||||
// Do whatever the fuck you want with it
|
||||
// Author: dkanus
|
||||
// E-mail: dkanus@gmail.com
|
||||
//======================================================================================================================
|
||||
class NiceBulletAdapter extends Object;
|
||||
|
||||
var const int BigZedMinHealth; // If zed's base Health >= this value, zed counts as Big
|
||||
var const int MediumZedMinHealth; // If zed's base Health >= this value, zed counts as Medium-size
|
||||
|
||||
static function Explode(
|
||||
NiceBullet bullet,
|
||||
NiceReplicationInfo niceRI,
|
||||
Vector hitLocation,
|
||||
optional Actor explosionTarget
|
||||
) {
|
||||
if (!bullet.bGhost) {
|
||||
niceRI.ServerExplode(
|
||||
bullet.charExplosionDamage,
|
||||
bullet.charExplosionRadius,
|
||||
bullet.charExplosionExponent,
|
||||
bullet.charExplosionDamageType,
|
||||
bullet.charExplosionMomentum,
|
||||
hitLocation,
|
||||
bullet.instigator,
|
||||
explosionTarget,
|
||||
Vector(bullet.Rotation),
|
||||
bullet.bStuck
|
||||
);
|
||||
|
||||
if (KFMonster(bullet.base) != none && bullet.bStuck && bullet.bStuckToHead) {
|
||||
niceRI.ServerDealDamage(
|
||||
KFMonster(bullet.base),
|
||||
bullet.charExplosionDamage,
|
||||
bullet.instigator,
|
||||
hitLocation,
|
||||
bullet.charExplosionMomentum * vect(0, 0, -1),
|
||||
bullet.charExplosionDamageType,
|
||||
1.0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function HandleCalibration (
|
||||
bool isHeadshot,
|
||||
NiceHumanPawn nicePawn,
|
||||
NiceMonster targetZed
|
||||
) {
|
||||
if (nicePawn == none || nicePawn.currentCalibrationState != CALSTATE_ACTIVE) {
|
||||
return;
|
||||
}
|
||||
|
||||
nicePawn.ServerUpdateCalibration(isHeadshot, targetZed);
|
||||
}
|
||||
|
||||
static function HitWall(
|
||||
NiceBullet bullet,
|
||||
NiceReplicationInfo niceRI,
|
||||
Actor targetWall,
|
||||
Vector hitLocation,
|
||||
Vector hitNormal
|
||||
) {
|
||||
local NicePlayerController nicePlayer;
|
||||
|
||||
nicePlayer = NicePlayerController(bullet.Instigator.Controller);
|
||||
if (nicePlayer == none) {
|
||||
return;
|
||||
}
|
||||
if (!bullet.bAlreadyHitZed) {
|
||||
HandleCalibration(false, NiceHumanPawn(bullet.Instigator), none);
|
||||
}
|
||||
if (
|
||||
!targetWall.bStatic &&
|
||||
!targetWall.bWorldGeometry &&
|
||||
nicePlayer != none &&
|
||||
(nicePlayer.wallHitsLeft > 0 || Projectile(targetWall) != none)
|
||||
) {
|
||||
niceRI.ServerDealDamage(
|
||||
targetWall,
|
||||
bullet.charOrigDamage,
|
||||
bullet.Instigator,
|
||||
hitLocation,
|
||||
bullet.charMomentumTransfer * hitNormal,
|
||||
bullet.charDamageType
|
||||
);
|
||||
nicePlayer.wallHitsLeft --;
|
||||
}
|
||||
}
|
||||
|
||||
static function HandleScream(
|
||||
NiceBullet bullet,
|
||||
NiceReplicationInfo niceRI,
|
||||
Vector location,
|
||||
Vector entryDirection
|
||||
) {
|
||||
bullet.charIsDud = true;
|
||||
}
|
||||
|
||||
static function HitPawn(
|
||||
NiceBullet bullet,
|
||||
NiceReplicationInfo niceRI,
|
||||
KFPawn targetPawn,
|
||||
Vector hitLocation,
|
||||
Vector hitNormal,
|
||||
array<int> hitPoints
|
||||
) {
|
||||
local NiceMedicProjectile niceDart;
|
||||
|
||||
niceDart = NiceMedicProjectile(bullet);
|
||||
if (niceDart == none) {
|
||||
niceRI.ServerDealDamage(
|
||||
targetPawn,
|
||||
bullet.charDamage,
|
||||
bullet.instigator,
|
||||
HitLocation,
|
||||
hitNormal * bullet.charMomentumTransfer,
|
||||
bullet.charDamageType
|
||||
);
|
||||
} else {
|
||||
niceRI.ServerHealTarget(NiceHumanPawn(targetPawn), bullet.charDamage, bullet.instigator);
|
||||
}
|
||||
}
|
||||
|
||||
static function HitZed(
|
||||
NiceBullet bullet,
|
||||
NiceReplicationInfo niceRI,
|
||||
KFMonster kfZed,
|
||||
Vector hitLocation,
|
||||
Vector hitNormal,
|
||||
float headshotLevel
|
||||
) {
|
||||
local bool bIsHeadshot, bIsPreciseHeadshot;
|
||||
local float actualDamage;
|
||||
local int lockonTicks;
|
||||
local float lockOnTickRate;
|
||||
local float angle;
|
||||
local NiceHumanPawn nicePawn;
|
||||
local NicePlayerController nicePlayer;
|
||||
local class<NiceVeterancyTypes> niceVet;
|
||||
|
||||
nicePlayer = NicePlayerController(bullet.Instigator.Controller);
|
||||
if (
|
||||
nicePlayer != none &&
|
||||
nicePlayer.abilityManager != none &&
|
||||
nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillEnforcerBruteA'.default.abilityID)
|
||||
) {
|
||||
headshotLevel = 0.0;
|
||||
}
|
||||
bIsHeadshot = (headshotLevel > 0.0);
|
||||
bIsPreciseHeadshot = (headshotLevel > bullet.charDamageType.default.prReqPrecise);
|
||||
if (!bullet.bAlreadyHitZed || bIsHeadshot) {
|
||||
HandleCalibration(bIsHeadshot, NiceHumanPawn(bullet.Instigator), NiceMonster(kfZed));
|
||||
}
|
||||
if (bIsHeadshot && bullet.sourceWeapon != none) {
|
||||
bullet.sourceWeapon.lastHeadshotTime = bullet.Level.TimeSeconds;
|
||||
}
|
||||
if (nicePlayer == none) {
|
||||
return;
|
||||
}
|
||||
nicePawn = NiceHumanPawn(bullet.instigator);
|
||||
if (
|
||||
!bIsHeadshot &&
|
||||
nicePawn != none &&
|
||||
nicePlayer.abilityManager != none &&
|
||||
nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillSharpshooterReaperA'.default.abilityID)
|
||||
) {
|
||||
nicePawn.ServerCooldownAbility(class'NiceSkillSharpshooterReaperA'.default.abilityID);
|
||||
}
|
||||
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo));
|
||||
if (bullet.charCausePain) {
|
||||
actualDamage = bullet.charOrigDamage;
|
||||
} else {
|
||||
actualDamage = bullet.charDamage;
|
||||
}
|
||||
if (headshotLevel > 0) {
|
||||
actualDamage *= bullet.charContiniousBonus;
|
||||
}
|
||||
if (bullet.bGrazing) {
|
||||
actualDamage *= class'NiceSkillSupportGraze'.default.grazeDamageMult;
|
||||
}
|
||||
bullet.bGrazing = false;
|
||||
if (
|
||||
kfZed == bullet.lockonZed &&
|
||||
bullet.lockonTime > bullet.sourceWeapon.stdFireRate &&
|
||||
niceVet != none &&
|
||||
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterKillConfirmed')
|
||||
) {
|
||||
lockOnTickRate =class'NiceSkillSharpshooterKillConfirmed'.default.stackDelay;
|
||||
lockonTicks = Ceil(bullet.lockonTime / lockOnTickRate) - 1;
|
||||
lockonTicks = Min(class'NiceSkillSharpshooterKillConfirmed'.default.maxStacks, lockonTicks);
|
||||
// actualDamage *= 1.0 +
|
||||
// 0.5 * lockonTicks * (lockonTicks + 1) * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus;
|
||||
// damageMod *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus;
|
||||
actualDamage *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus;
|
||||
}
|
||||
if (!bullet.bGhost) {
|
||||
niceRI.ServerDealDamage(
|
||||
kfZed,
|
||||
actualDamage,
|
||||
bullet.instigator,
|
||||
hitLocation,
|
||||
bullet.charMomentumTransfer * hitNormal,
|
||||
bullet.charDamageType,
|
||||
headshotLevel,
|
||||
bullet.lockonTime
|
||||
);
|
||||
}
|
||||
//// Handle angled shots
|
||||
angle = asin(hitNormal.Z);
|
||||
// Apply angled shots
|
||||
if ((angle > 0.8 || angle < -0.45) && bullet.bCanAngleDamage && kfZed != none) {
|
||||
bullet.bCanAngleDamage = false;
|
||||
bullet.bAlreadyHitZed = true;
|
||||
if (ZedPenetration(bullet.charDamage, bullet, kfZed, bIsHeadshot, bIsPreciseHeadshot)) {
|
||||
HitZed(bullet, niceRI, kfZed, hitLocation, hitNormal, headshotLevel);
|
||||
}
|
||||
}
|
||||
//// 'Bore' support skill
|
||||
if (
|
||||
niceVet != none &&
|
||||
nicePlayer.IsZedTimeActive() &&
|
||||
bullet.insideBouncesLeft > 0 &&
|
||||
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBore')
|
||||
) {
|
||||
// Count one bounce
|
||||
bullet.insideBouncesLeft --;
|
||||
// Swap head-shot level
|
||||
if (headshotLevel <= 0.0) {
|
||||
headshotLevel = class'NiceSkillSupportZEDBore'.default.minHeadshotPrecision;
|
||||
} else {
|
||||
headshotLevel = -headshotLevel;
|
||||
}
|
||||
// Deal next batch of damage
|
||||
ZedPenetration(bullet.charDamage, bullet, kfZed, false, false);
|
||||
HitZed(bullet, niceRI, kfZed, hitLocation, hitNormal, headshotLevel);
|
||||
}
|
||||
bullet.insideBouncesLeft = 2;
|
||||
}
|
||||
|
||||
static function bool ZedPenetration(
|
||||
out float Damage,
|
||||
NiceBullet bullet,
|
||||
KFMonster targetZed,
|
||||
bool bIsHeadshot,
|
||||
bool bIsPreciseHeadshot
|
||||
) {
|
||||
local float reductionMod;
|
||||
local NiceMonster niceZed;
|
||||
local NicePlayerController nicePlayer;
|
||||
local int actualMaxPenetrations;
|
||||
local class<NiceVeterancyTypes> niceVet;
|
||||
local class<NiceWeaponDamageType> niceDmgType;
|
||||
// True if we can penetrate even body, but now penetrating a head and shouldn't reduce damage too much
|
||||
local bool bEasyHeadPenetration;
|
||||
|
||||
// Init variables
|
||||
niceZed = NiceMonster(targetZed);
|
||||
nicePlayer = NicePlayerController(bullet.Instigator.Controller);
|
||||
niceVet = none;
|
||||
if (nicePlayer != none) {
|
||||
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo));
|
||||
}
|
||||
niceDmgType = bullet.charDamageType;
|
||||
bEasyHeadPenetration = bIsHeadshot && !niceDmgType.default.bPenetrationHSOnly;
|
||||
reductionMod = 1.0f;
|
||||
// Apply zed reduction and perk reduction of reduction`
|
||||
if (niceZed != none) {
|
||||
// Railgun skill exception
|
||||
if (
|
||||
niceVet != none &&
|
||||
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterZEDRailgun') &&
|
||||
nicePlayer.IsZedTimeActive()
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (niceZed.default.Health >= default.BigZedMinHealth && !bEasyHeadPenetration) {
|
||||
reductionMod *= niceDmgType.default.BigZedPenDmgReduction;
|
||||
} else if (niceZed.default.Health >= default.MediumZedMinHealth && !bEasyHeadPenetration) {
|
||||
reductionMod *= niceDmgType.default.MediumZedPenDmgReduction;
|
||||
}
|
||||
} else {
|
||||
reductionMod *= niceDmgType.default.BigZedPenDmgReduction;
|
||||
}
|
||||
if (niceVet != none) {
|
||||
reductionMod = niceVet.static.GetPenetrationDamageMulti(
|
||||
KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo),
|
||||
reductionMod,
|
||||
niceDmgType
|
||||
);
|
||||
}
|
||||
actualMaxPenetrations = niceDmgType.default.maxPenetrations;
|
||||
if (
|
||||
niceVet != none &&
|
||||
!bullet.charWasHipFired &&
|
||||
niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterSurgical') &&
|
||||
bIsHeadshot
|
||||
) {
|
||||
actualMaxPenetrations += 1;
|
||||
reductionMod = FMax(reductionMod, class'NiceSkillSharpshooterSurgical'.default.penDmgReduction);
|
||||
}
|
||||
// Assign new damage value and tell us if we should stop with penetration
|
||||
Damage *= reductionMod * niceDmgType.default.PenDmgReduction;
|
||||
bullet.decapMod *= reductionMod * niceDmgType.default.PenDecapReduction;
|
||||
bullet.incapMod *= reductionMod * niceDmgType.default.PenIncapReduction;
|
||||
if (niceVet != none && actualMaxPenetrations >= 0) {
|
||||
actualMaxPenetrations +=
|
||||
niceVet.static.GetAdditionalPenetrationAmount(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo));
|
||||
}
|
||||
if (!bIsHeadshot && niceDmgType.default.bPenetrationHSOnly) {
|
||||
return false;
|
||||
}
|
||||
if (actualMaxPenetrations < 0) {
|
||||
return true;
|
||||
}
|
||||
if (Damage / bullet.charOrigDamage < (niceDmgType.default.PenDmgReduction ** (actualMaxPenetrations + 1)) + 0.0001 || Damage < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
defaultproperties {
|
||||
BigZedMinHealth=1000
|
||||
MediumZedMinHealth=500
|
||||
}
|
||||
53
kf_sources/NicePack/Classes/NiceBullpup.uc
Normal file
53
kf_sources/NicePack/Classes/NiceBullpup.uc
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
class NiceBullpup extends NiceAssaultRifle;
|
||||
#exec OBJ LOAD FILE=KillingFloorWeapons.utx
|
||||
#exec OBJ LOAD FILE=KillingFloorHUD.utx
|
||||
#exec OBJ LOAD FILE=Inf_Weapons_Foley.uax
|
||||
defaultproperties
|
||||
{
|
||||
reloadPreEndFrame=0.333000
|
||||
reloadEndFrame=0.783000
|
||||
reloadChargeEndFrame=-1.000000
|
||||
reloadMagStartFrame=0.483000
|
||||
reloadChargeStartFrame=-1.000000
|
||||
MagCapacity=30
|
||||
ReloadRate=1.966667
|
||||
ReloadAnim="Reload"
|
||||
ReloadAnimRate=1.000000
|
||||
WeaponReloadAnim="Reload_BullPup"
|
||||
Weight=5.000000
|
||||
bHasAimingMode=True
|
||||
IdleAimAnim="Idle_Iron"
|
||||
StandardDisplayFOV=70.000000
|
||||
SleeveNum=2
|
||||
TraderInfoTexture=Texture'KillingFloorHUD.Trader_Weapon_Images.Trader_Bullpup'
|
||||
MeshRef="KF_Weapons_Trip.Bullpup_Trip"
|
||||
SkinRefs(0)="KF_Weapons_Trip_T.Rifles.bullpup_cmb"
|
||||
SkinRefs(1)="KF_Weapons_Trip_T.Rifles.reflex_sight_A_unlit"
|
||||
SelectSoundRef="KF_BullpupSnd.Bullpup_Select"
|
||||
HudImageRef="KillingFloorHUD.WeaponSelect.Bullpup_unselected"
|
||||
SelectedHudImageRef="KillingFloorHUD.WeaponSelect.Bullpup"
|
||||
PlayerIronSightFOV=65.000000
|
||||
ZoomedDisplayFOV=40.000000
|
||||
FireModeClass(0)=class'NiceBullpupFire'
|
||||
FireModeClass(1)=Class'KFMod.NoFire'
|
||||
PutDownAnim="PutDown"
|
||||
SelectForce="SwitchToAssaultRifle"
|
||||
AIRating=0.550000
|
||||
CurrentRating=0.550000
|
||||
bShowChargingBar=True
|
||||
Description="A military grade automatic rifle. Can be fired in semi-auto or full auto firemodes and comes equipped with a scope for increased accuracy."
|
||||
EffectOffset=(X=100.000000,Y=25.000000,Z=-10.000000)
|
||||
DisplayFOV=70.000000
|
||||
Priority=70
|
||||
CustomCrosshair=11
|
||||
CustomCrossHairTextureName="Crosshairs.HUD.Crosshair_Cross5"
|
||||
InventoryGroup=3
|
||||
GroupOffset=1
|
||||
PickupClass=class'NiceBullpupPickup'
|
||||
PlayerViewOffset=(X=20.000000,Y=21.500000,Z=-9.000000)
|
||||
BobDamping=6.000000
|
||||
AttachmentClass=class'NiceBullpupAttachment'
|
||||
IconCoords=(X1=245,Y1=39,X2=329,Y2=79)
|
||||
ItemName="Bullpup"
|
||||
TransientSoundVolume=1.250000
|
||||
}
|
||||
13
kf_sources/NicePack/Classes/NiceBullpupAmmo.uc
Normal file
13
kf_sources/NicePack/Classes/NiceBullpupAmmo.uc
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
class NiceBullpupAmmo extends NiceAmmo;
|
||||
#EXEC OBJ LOAD FILE=KillingFloorHUD.utx
|
||||
defaultproperties
|
||||
{
|
||||
WeaponPickupClass=class'NiceBullpupPickup'
|
||||
AmmoPickupAmount=30
|
||||
MaxAmmo=240
|
||||
InitialAmount=45
|
||||
PickupClass=class'NiceBullpupAmmoPickup'
|
||||
IconMaterial=Texture'KillingFloorHUD.Generic.HUD'
|
||||
IconCoords=(X1=336,Y1=82,X2=382,Y2=125)
|
||||
ItemName="Bullpup bullets"
|
||||
}
|
||||
8
kf_sources/NicePack/Classes/NiceBullpupAmmoPickup.uc
Normal file
8
kf_sources/NicePack/Classes/NiceBullpupAmmoPickup.uc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
class NiceBullpupAmmoPickup extends NiceAmmoPickup;
|
||||
defaultproperties
|
||||
{
|
||||
AmmoAmount=30
|
||||
InventoryType=class'NiceBullpupAmmo'
|
||||
PickupMessage="Rounds (5.56 NATO)"
|
||||
StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo'
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue