Jump to content

[HELP] Realistic RP Damage System


Justice

Recommended Posts

First off, I'd like to thank anyone that takes the time to help me out.

Down to business, I'm making a system that increases damage of weapons for use in a post-apocalyptic server, Zombie Roleplay. Separate from this, there is another system that will cause players to bleed if they're shot, as long as they're not already bleeding.

This script is meant to perform:


  • -Additional bullet damage, aiming for realism. Makes many GTA weapons kill in only a few shots.
    -Additional damage falls off over range due to air resistance on the bullet.
    -A sniper hit to the chest will knock a player out. (That code is separate in another system and not part of this issue.)

However I'm running into a snag. From certain distances and angles and even randomly, the onPlayerDamage() server side event appears to be triggering more than once. Since the script relies on it to tell when the player has been damaged, it needs to be accurate.

Also, the setWeaponProperty for the weapon range is not working. At least, not in the Freeroam gamemode.

I'm wondering, is there anything we can do about this without waiting for a fix from MTA devs?

Here is the code for those that wish to test for themselves. It's all server-side, as I ran into syncing issues when using client side.

--[[ 
Author: Jordan 
Date: September 26, 2015 
Purpose: Create a realistic system for increasing bullet damage in a roleplay setting. 
Also, cause extra damage to drop off as bullets are affected by air resistance over long distances. 
]] 
  
function RPDamage (attacker, weapon, bodypart) 
  
  
--THIS FUCKIN SHIT DON'T WORK. CONSTANTLY FUCKIN' TRIGGERING TWICE ON THE ZRP SERVER ONLY!!! 
    if attacker == nil then -- Covering an error I got randomly sometimes where attacker wasn't met. 
        attacker = source 
    end 
    local x,y,z = getElementPosition( source ) 
    local ex,ey,ez = getElementPosition( attacker ) 
    local distance = (getDistanceBetweenPoints3D (ex, ey, ez, x, y, z)) 
    -- If someone attacks someone with a weapon not on this list, it will return an error can't compare nil. This is normal. 
    -- In the future could populate list with every weapon in the game, just with 0 values. 
    local weaponDamage = {["Colt 45"] = 20, ["Silenced"] = 20, ["Deagle"] = 25, ["Shotgun"] = 55, ["Sawed-off"] = 30, ["Combat Shotgun"] = 35, ["Uzi"] = 10, ["MP5"] = 12, ["AK-47"] = 33, ["M4"] = 24, ["Tec-9"] = 10, ["Rifle"] = 44, ["Sniper"] = 58, ["Brassknuckle"] = 0, ["Golfclub"] = 0, ["Nightstick"] = 0, ["Knife"] = 0, ["Bat"] = 0, ["Shovel"] = 0, ["Poolstick"] = 0, ["Katana"] = 0, ["Chainsaw"] = 0, ["Dildo"] = 0, ["Vibrator"] = 0, ["Flower"] = 0, ["Fist"] = 0, ["Cane"] = 0, ["Teargas"] = 0, ["Minigun"] = 0, ["Spraycan"] = 0, ["Fire Extinguisher"] = 0, ["Drowned"] = 0-1} 
    local weaponDamageModifier = {["Colt 45"] = 1/((distance+0.001)/15), ["Silenced"] = 1/((distance+0.001)/10), ["Deagle"] = 1/((distance+0.001)/15), ["Shotgun"] = 1/((distance+0.001)/8), ["Sawed-off"] = 1/((distance+0.001)/3), ["Combat Shotgun"] = 1/((distance+0.001)/5), ["Uzi"] = 1/((distance+0.001)/12), ["MP5"] = 1/((distance+0.001)/18), ["AK-47"] = 1/((distance+0.001)/15), ["M4"] = 1/((distance+0.001)/30), ["Tec-9"] = 1/((distance+0.001)/12), ["Rifle"] = 1/((distance+0.001)/40), ["Sniper"] = 1/((distance+0.001)/50), ["Brassknuckle"] = 1, ["Golfclub"] = 1, ["Nightstick"] = 1, ["Knife"] = 1, ["Bat"] = 1, ["Shovel"] = 1, ["Poolstick"] = 1, ["Katana"] = 1, ["Chainsaw"] = 1, ["Dildo"] = 1, ["Vibrator"] = 1, ["Flower"] = 1, ["Fist"] = 1, ["Cane"] = 1, ["Teargas"] = 1, ["Minigun"] = 1, ["Spraycan"] = 1, ["Fire Extinguisher"] = 1, ["Drowned"] = 1} 
    local weaponName = getWeaponNameFromID(weapon) 
    local originalDamage = weaponDamage[weaponName] 
    local modifierDamage = weaponDamageModifier[weaponName] 
     
  
    if bodypart == 3 and getPedArmor(source) == 0 and distance > 0.85 then 
        if weapon == 34 then 
            --call(getResourceFromName ( "lses-system" ), "knockout", source) 
            outputChatBox("KO! Sniper to the chest!") 
        end 
        if modifierDamage ~= nil then -- This covers for the problem in line 11. It avoids the entire calculation if the weapon isn't in the list. 
            if modifierDamage > 1 then 
                local damageMod = originalDamage 
                outputChatBox("FULL EXTRA DAMAGE!") 
                if getElementHealth(source) <= damageMod then 
                    killPed (source, attacker, weapon, bodypart, false) 
                else 
                    setElementHealth(source, getElementHealth(source) - damageMod) 
                    outputChatBox("Damage after falloff: " .. tostring(damageMod)) 
                end 
            else 
                local damageMod = math.ceil(originalDamage * modifierDamage) -- Round up, will always do one extra damage. 
                outputChatBox("Extra damage is falling off.") 
                if getElementHealth(source) <= damageMod then 
                    killPed (source, attacker, weapon, bodypart, false) 
                else 
                    setElementHealth(source, getElementHealth(source) - damageMod) 
                    outputChatBox("Damage after falloff: " .. tostring(damageMod)) 
                end 
            end 
        end 
    end 
     
     
    outputChatBox("-------------------------------------------------------") 
    outputChatBox("Weapon: " .. tostring(weaponName)) 
    outputChatBox("Distance: " .. tostring(distance)) 
    outputChatBox("Extra damage: " .. tostring(originalDamage)) 
    outputChatBox("Multiplyer: " .. tostring(modifierDamage)) 
    outputChatBox("Bone: " .. tostring(bodypart)) 
    outputChatBox("-------------------------------------------------------") 
    outputChatBox("Health after: " .. tostring(getElementHealth(source))) 
  
     
end 
  
function weaponStats() 
    setWeaponProperty(38, "std", "damage", 10) 
    setWeaponProperty(38, "pro", "damage", 10) 
    setWeaponProperty(38, "poor", "damage", 10) 
    setWeaponProperty(22, "std", "weapon_range", 500.0) 
    setWeaponProperty(22, "pro", "weapon_range", 500.0) 
    setWeaponProperty(22, "poor", "weapon_range", 500.0) 
    setWeaponProperty(23, "std", "weapon_range", 500.0) 
    setWeaponProperty(23, "pro", "weapon_range", 500.0) 
    setWeaponProperty(23, "poor", "weapon_range", 500.0) 
    setWeaponProperty(24, "std", "weapon_range", 500.0) 
    setWeaponProperty(24, "pro", "weapon_range", 500.0) 
    setWeaponProperty(24, "poor", "weapon_range", 500.0) 
    setWeaponProperty(25, "std", "weapon_range", 500.0) 
    setWeaponProperty(25, "pro", "weapon_range", 500.0) 
    setWeaponProperty(25, "poor", "weapon_range", 500.0) 
    setWeaponProperty(26, "std", "weapon_range", 500.0) 
    setWeaponProperty(26, "pro", "weapon_range", 500.0) 
    setWeaponProperty(26, "poor", "weapon_range", 500.0) 
    setWeaponProperty(27, "std", "weapon_range", 500.0) 
    setWeaponProperty(27, "pro", "weapon_range", 500.0) 
    setWeaponProperty(27, "poor", "weapon_range", 500.0) 
    setWeaponProperty(28, "std", "weapon_range", 500.0) 
    setWeaponProperty(28, "pro", "weapon_range", 500.0) 
    setWeaponProperty(28, "poor", "weapon_range", 500.0) 
    setWeaponProperty(29, "std", "weapon_range", 500.0) 
    setWeaponProperty(29, "pro", "weapon_range", 500.0) 
    setWeaponProperty(29, "poor", "weapon_range", 500.0) 
    setWeaponProperty(30, "std", "weapon_range", 500.0) 
    setWeaponProperty(30, "pro", "weapon_range", 500.0) 
    setWeaponProperty(30, "poor", "weapon_range", 500.0) 
    setWeaponProperty(31, "std", "weapon_range", 500.0) 
    setWeaponProperty(31, "pro", "weapon_range", 500.0) 
    setWeaponProperty(31, "poor", "weapon_range", 500.0) 
    setWeaponProperty(32, "std", "weapon_range", 500.0) 
    setWeaponProperty(32, "pro", "weapon_range", 500.0) 
    setWeaponProperty(32, "poor", "weapon_range", 500.0) 
    setWeaponProperty(33, "std", "weapon_range", 500.0) 
    setWeaponProperty(33, "pro", "weapon_range", 500.0) 
    setWeaponProperty(33, "poor", "weapon_range", 500.0) 
    outputChatBox("Now AK range: " .. tostring(getWeaponProperty(30, "pro", "weapon_range"))) 
    outputChatBox("Original AK range: " .. tostring(getOriginalWeaponProperty(30, "pro", "weapon_range"))) 
end 
  
addEventHandler ("onPlayerDamage", getRootElement(), RPDamage) 
addEventHandler ("onResourceStart", getRootElement(), weaponStats) 

PS: I've never scripted in LUA before, so feel free to let me know how I've done.

Edited by Guest
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...