mirror of
				https://github.com/coop-deluxe/sm64coopdx.git
				synced 2025-10-30 08:01:01 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			593 lines
		
	
	
		
			No EOL
		
	
	
		
			18 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			593 lines
		
	
	
		
			No EOL
		
	
	
		
			18 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
if SM64COOPDX_VERSION == nil then return end
 | 
						|
 | 
						|
---------------------------------------
 | 
						|
-- API and other important functions --
 | 
						|
---------------------------------------
 | 
						|
 | 
						|
--- @class Weapon
 | 
						|
--- @field public id integer
 | 
						|
--- @field public name string
 | 
						|
--- @field public dualWield boolean
 | 
						|
--- @field public model ModelExtendedId
 | 
						|
--- @field public armModel ModelExtendedId
 | 
						|
--- @field public bulletModel ModelExtendedId
 | 
						|
--- @field public primarySounds integer[]
 | 
						|
--- @field public secondarySounds integer[]
 | 
						|
--- @field public strong boolean
 | 
						|
--- @field public rapidFire boolean
 | 
						|
--- @field public spread number
 | 
						|
--- @field public damage number
 | 
						|
--- @field public bulletCount integer
 | 
						|
--- @field public bulletScale number
 | 
						|
--- @field public bulletSpeed number
 | 
						|
--- @field public bulletSteps integer
 | 
						|
--- @field public maxAmmo integer
 | 
						|
--- @field public ammo integer
 | 
						|
--- @field public deployTime integer
 | 
						|
--- @field public cooldownTime integer
 | 
						|
--- @field public reloadTime integer
 | 
						|
--- @field public deployTimer integer
 | 
						|
--- @field public cooldownTimer integer
 | 
						|
--- @field public reloadTimer integer
 | 
						|
--- @field public primaryFireFunc fun(weapon:Weapon)
 | 
						|
--- @field public secondaryFireFunc fun(weapon:Weapon)
 | 
						|
--- @field public reqCheck fun(m:MarioState)
 | 
						|
 | 
						|
--- @class WeaponId
 | 
						|
 | 
						|
--- @type Weapon[]
 | 
						|
gWeaponTable = {}
 | 
						|
--- @type Weapon[]
 | 
						|
gInventory = {}
 | 
						|
for i = 1, MAX_INVENTORY_SLOTS do gInventory[i] = nil end
 | 
						|
inventorySlot = 1
 | 
						|
useDualWieldWeapon = false
 | 
						|
 | 
						|
local weaponObtained = false
 | 
						|
local weaponId = -1
 | 
						|
 | 
						|
local sMutableWeaponFields = {
 | 
						|
    ["ammo"] = true,
 | 
						|
    ["deployTimer"] = true,
 | 
						|
    ["cooldownTimer"] = true,
 | 
						|
    ["reloadTimer"] = true
 | 
						|
}
 | 
						|
 | 
						|
local sReadonlyMetatable = {
 | 
						|
    __index = function(table, key)
 | 
						|
        return rawget(table, key)
 | 
						|
    end,
 | 
						|
 | 
						|
    __newindex = function()
 | 
						|
        error("attempt to update a read-only table", 2)
 | 
						|
    end
 | 
						|
}
 | 
						|
 | 
						|
local sWeaponMetatable = {
 | 
						|
    __index = function(table, key)
 | 
						|
        return rawget(table, key)
 | 
						|
    end,
 | 
						|
 | 
						|
    __newindex = function(table, key, value)
 | 
						|
        if sMutableWeaponFields[key] then
 | 
						|
            rawset(table, key, value)
 | 
						|
        else
 | 
						|
            error("attempt to update an immutable weapon field", 2)
 | 
						|
        end
 | 
						|
    end
 | 
						|
}
 | 
						|
 | 
						|
--- @param name string
 | 
						|
--- @param dualWield boolean
 | 
						|
--- @param model ModelExtendedId
 | 
						|
--- @param armModel ModelExtendedId
 | 
						|
--- @param bulletModel ModelExtendedId
 | 
						|
--- @param primarySounds integer[]
 | 
						|
--- @param secondarySounds integer[]
 | 
						|
--- @param strong boolean
 | 
						|
--- @param rapidFire boolean
 | 
						|
--- @param spread number
 | 
						|
--- @param damage number
 | 
						|
--- @param bulletCount integer
 | 
						|
--- @param bulletScale number
 | 
						|
--- @param bulletSpeed number
 | 
						|
--- @param bulletSteps integer
 | 
						|
--- @param maxAmmo integer
 | 
						|
--- @param deployTime integer
 | 
						|
--- @param cooldownTime integer
 | 
						|
--- @param reloadTime integer
 | 
						|
--- @param primaryFireFunc fun(weapon:Weapon)
 | 
						|
--- @param secondaryFireFunc fun(weapon:Weapon)
 | 
						|
--- @param reqCheck function
 | 
						|
--- @return integer
 | 
						|
--- Registers a weapon metatable into existence
 | 
						|
function weapon_register(name, dualWield, model, armModel, bulletModel, primarySounds, secondarySounds, strong, rapidFire, spread, damage, bulletCount, bulletScale, bulletSpeed, bulletSteps, maxAmmo, deployTime, cooldownTime, reloadTime, primaryFireFunc, secondaryFireFunc, reqCheck)
 | 
						|
    weaponId = weaponId + 1
 | 
						|
    gWeaponTable[weaponId] = {
 | 
						|
        id = weaponId,
 | 
						|
        name = name,
 | 
						|
        dualWield = dualWield,
 | 
						|
        model = model,
 | 
						|
        armModel = armModel,
 | 
						|
        bulletModel = bulletModel,
 | 
						|
        primarySounds = primarySounds,
 | 
						|
        secondarySounds = secondarySounds,
 | 
						|
        strong = strong,
 | 
						|
        rapidFire = rapidFire,
 | 
						|
        spread = spread,
 | 
						|
        damage = damage,
 | 
						|
        bulletCount = bulletCount,
 | 
						|
        bulletScale = bulletScale,
 | 
						|
        bulletSpeed = bulletSpeed,
 | 
						|
        bulletSteps = bulletSteps,
 | 
						|
        maxAmmo = maxAmmo,
 | 
						|
        ammo = maxAmmo,
 | 
						|
        deployTime = deployTime,
 | 
						|
        cooldownTime = cooldownTime,
 | 
						|
        reloadTime = reloadTime,
 | 
						|
        deployTimer = deployTime,
 | 
						|
        cooldownTimer = 0,
 | 
						|
        reloadTimer = 0,
 | 
						|
        primaryFireFunc = primaryFireFunc,
 | 
						|
        secondaryFireFunc = secondaryFireFunc,
 | 
						|
        reqCheck = reqCheck
 | 
						|
    }
 | 
						|
    setmetatable(gWeaponTable[weaponId], sReadonlyMetatable)
 | 
						|
    return weaponId
 | 
						|
end
 | 
						|
 | 
						|
--- @param id integer
 | 
						|
--- @return nil
 | 
						|
--- Unregisters a weapon from existence by ID
 | 
						|
function weapon_unregister(id)
 | 
						|
    if type(id) ~= "number" then return end
 | 
						|
    gWeaponTable[id] = nil
 | 
						|
end
 | 
						|
 | 
						|
--- @return nil
 | 
						|
--- Unregisters all weapons from existence
 | 
						|
function weapon_unregister_all()
 | 
						|
    gWeaponTable = {}
 | 
						|
end
 | 
						|
 | 
						|
--- @return string
 | 
						|
--- Properly formatted weapon list string for commands
 | 
						|
function get_weapon_list_string()
 | 
						|
    local string = "["
 | 
						|
    for id, weapon in pairs(gWeaponTable) do
 | 
						|
        string = string .. weapon.name:lower()
 | 
						|
        if id < weaponId then
 | 
						|
            string = string .. "|"
 | 
						|
        end
 | 
						|
    end
 | 
						|
    string = string .. "]"
 | 
						|
    return string
 | 
						|
end
 | 
						|
 | 
						|
--- @param obj Object
 | 
						|
--- @param owner integer
 | 
						|
--- @param id integer
 | 
						|
--- @param dualWield integer
 | 
						|
--- @param extra integer
 | 
						|
--- @return nil
 | 
						|
--- Returns a 4 byte behavior parameter integer for weapon objects.
 | 
						|
function obj_set_weapon_params(obj, owner, id, dualWield, extra)
 | 
						|
    if obj == nil then return end
 | 
						|
    if type(owner) ~= "number" or type(id) ~= "number" or type(dualWield) ~= "number" or type(extra) ~= "number" then return end
 | 
						|
    obj.oBehParams = owner | (id << 8) | (dualWield << 16) | (extra << 24)
 | 
						|
    obj.oBehParams2ndByte = id
 | 
						|
end
 | 
						|
 | 
						|
--- @param obj Object
 | 
						|
--- @return integer
 | 
						|
--- Returns the owner parameter (first parameter) of a weapon object.
 | 
						|
function obj_get_weapon_owner(obj)
 | 
						|
    if obj == nil then return 0 end
 | 
						|
    return obj.oBehParams & 0xFF
 | 
						|
end
 | 
						|
 | 
						|
--- @param obj Object
 | 
						|
--- @return integer
 | 
						|
--- Returns the id parameter (second parameter) of a weapon object.
 | 
						|
function obj_get_weapon_id(obj)
 | 
						|
    if obj == nil then return 0 end
 | 
						|
    return obj.oBehParams2ndByte
 | 
						|
end
 | 
						|
 | 
						|
--- @param obj Object
 | 
						|
--- @return integer
 | 
						|
--- Returns the dual wield parameter (third parameter) of a weapon object.
 | 
						|
function obj_get_weapon_dual_wield(obj)
 | 
						|
    if obj == nil then return 0 end
 | 
						|
    return (obj.oBehParams >> 16) & 0xFF
 | 
						|
end
 | 
						|
 | 
						|
--- @param obj Object
 | 
						|
--- @return integer
 | 
						|
--- Returns the extra parameter (fourth parameter) of a weapon object.
 | 
						|
function obj_get_weapon_extra(obj)
 | 
						|
    if obj == nil then return 0 end
 | 
						|
    return (obj.oBehParams >> 24) & 0xFF
 | 
						|
end
 | 
						|
 | 
						|
--- @return Weapon|nil
 | 
						|
--- Returns the table of the current weapon
 | 
						|
function cur_weapon()
 | 
						|
    return gInventory[inventorySlot]
 | 
						|
end
 | 
						|
 | 
						|
--- @return Weapon|nil
 | 
						|
--- Returns the table of the current dual wielding weapon
 | 
						|
function cur_dual_wield_weapon()
 | 
						|
    local weapon = cur_weapon()
 | 
						|
    if weapon == nil or not weapon.dualWield then return nil end
 | 
						|
 | 
						|
    local weaponBefore = gInventory[inventorySlot - 1]
 | 
						|
    if weaponBefore ~= nil and weaponBefore.dualWield and weaponBefore.id == weapon.id then return weaponBefore end
 | 
						|
 | 
						|
    local weaponAfter = gInventory[inventorySlot + 1]
 | 
						|
    if weaponAfter ~= nil and weaponAfter.dualWield and weaponAfter.id == weapon.id then return weaponAfter end
 | 
						|
 | 
						|
    return nil
 | 
						|
end
 | 
						|
 | 
						|
--- @return integer
 | 
						|
--- Returns the current inventory slot
 | 
						|
function get_inventory_slot()
 | 
						|
    return inventorySlot
 | 
						|
end
 | 
						|
 | 
						|
--- @param slot integer
 | 
						|
--- @return nil
 | 
						|
--- Sets the current inventory slot
 | 
						|
function set_inventory_slot(slot)
 | 
						|
    if type(slot) ~= "number" then return end
 | 
						|
 | 
						|
    -- reset fields
 | 
						|
    gInventory[slot].deployTimer = gInventory[slot].deployTime
 | 
						|
    gInventory[slot].cooldownTimer = 0
 | 
						|
    gInventory[slot].reloadTimer = if_then_else(gInventory[slot].ammo <= 0 and gInventory[slot].maxAmmo > 0, gInventory[slot].reloadTime, 0)
 | 
						|
 | 
						|
    inventorySlot = clamp(slot, 1, MAX_INVENTORY_SLOTS)
 | 
						|
    sync_current_weapons()
 | 
						|
    delete_held_weapon()
 | 
						|
    if get_first_person_enabled() then
 | 
						|
        delete_viewmodels()
 | 
						|
        spawn_viewmodels()
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
local function table_clone(table)
 | 
						|
    local cloned = {}
 | 
						|
    for k, v in pairs(table) do
 | 
						|
        if type(v) == "table" then
 | 
						|
            cloned[k] = table_clone(v)
 | 
						|
        else
 | 
						|
            cloned[k] = v
 | 
						|
        end
 | 
						|
    end
 | 
						|
    return cloned
 | 
						|
end
 | 
						|
 | 
						|
--- @param weapon WeaponId
 | 
						|
local function inventory_clone(weapon)
 | 
						|
    local table = table_clone(gWeaponTable[weapon])
 | 
						|
    setmetatable(table, sWeaponMetatable)
 | 
						|
    return table
 | 
						|
end
 | 
						|
 | 
						|
local function get_inventory_slots_used()
 | 
						|
    local count = 0
 | 
						|
    for i = 1, MAX_INVENTORY_SLOTS do
 | 
						|
        if gInventory[i] ~= nil then
 | 
						|
            count = count + 1
 | 
						|
        end
 | 
						|
    end
 | 
						|
    return count
 | 
						|
end
 | 
						|
 | 
						|
--- @param weapon WeaponId
 | 
						|
--- @return boolean
 | 
						|
--- Picks up a weapon by ID
 | 
						|
function pickup_weapon(weapon)
 | 
						|
    if type(weapon) ~= "number" then return false end
 | 
						|
    for i = 1, MAX_INVENTORY_SLOTS do
 | 
						|
        if gInventory[i] == weapon then
 | 
						|
            return false
 | 
						|
        elseif gInventory[i] == nil or get_inventory_slots_used() == MAX_INVENTORY_SLOTS then
 | 
						|
            if not weaponObtained then
 | 
						|
                play_sound(SOUND_MENU_STAR_SOUND, gMarioStates[0].marioObj.header.gfx.cameraToObject)
 | 
						|
                weaponObtained = true
 | 
						|
            else
 | 
						|
                play_sound(SOUND_MENU_CLICK_CHANGE_VIEW, gMarioStates[0].marioObj.header.gfx.cameraToObject)
 | 
						|
            end
 | 
						|
 | 
						|
            gInventory[i] = inventory_clone(weapon)
 | 
						|
            set_inventory_slot(i)
 | 
						|
 | 
						|
            return true
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    return false
 | 
						|
end
 | 
						|
 | 
						|
function sync_current_weapons()
 | 
						|
    gPlayerSyncTable[0].curWeapon = nil
 | 
						|
    gPlayerSyncTable[0].curWeapon2 = nil
 | 
						|
 | 
						|
    local weapon = cur_weapon()
 | 
						|
    if weapon ~= nil then
 | 
						|
        gPlayerSyncTable[0].curWeapon = weapon.id
 | 
						|
    end
 | 
						|
    local weapon2 = cur_dual_wield_weapon()
 | 
						|
    if weapon2 ~= nil then
 | 
						|
        gPlayerSyncTable[0].curWeapon2 = weapon2.id
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
--- @param weapon Weapon
 | 
						|
function handle_reloading(weapon)
 | 
						|
    if weapon == nil then return end
 | 
						|
 | 
						|
    if weapon.reloadTimer > 0 then
 | 
						|
        weapon.reloadTimer = weapon.reloadTimer - 1
 | 
						|
        if weapon.name == "Shotgun" then
 | 
						|
            weapon.ammo = math.floor(lerp(weapon.maxAmmo, 0, weapon.reloadTimer / weapon.reloadTime))
 | 
						|
        end
 | 
						|
        if weapon.reloadTimer == 0 then
 | 
						|
            weapon.ammo = weapon.maxAmmo
 | 
						|
        end
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
function weapon_update()
 | 
						|
    --- @type MarioState
 | 
						|
    local m = gMarioStates[0]
 | 
						|
 | 
						|
    -- update inventory slot
 | 
						|
    if (m.controller.buttonPressed & U_JPAD) ~= 0 then
 | 
						|
        inventorySlot = inventorySlot + 1
 | 
						|
        if inventorySlot > MAX_INVENTORY_SLOTS then
 | 
						|
            inventorySlot = 1
 | 
						|
        end
 | 
						|
        set_inventory_slot(inventorySlot)
 | 
						|
    elseif (m.controller.buttonPressed & D_JPAD) ~= 0 then
 | 
						|
        inventorySlot = inventorySlot - 1
 | 
						|
        if inventorySlot < 1 then
 | 
						|
            inventorySlot = MAX_INVENTORY_SLOTS
 | 
						|
        end
 | 
						|
        set_inventory_slot(inventorySlot)
 | 
						|
    end
 | 
						|
 | 
						|
    local weapon1 = cur_weapon()
 | 
						|
    local weapon2 = cur_dual_wield_weapon()
 | 
						|
    --- @type Weapon
 | 
						|
    local weapon = if_then_else(weapon2 ~= nil and useDualWieldWeapon, weapon2, weapon1)
 | 
						|
    if weapon1 == nil then return end -- if the player isn't holding a weapon
 | 
						|
 | 
						|
    if weapon.deployTimer <= 0 and weapon.cooldownTimer <= 0 then
 | 
						|
        local buttonFlags = if_then_else(weapon.rapidFire, m.controller.buttonDown, m.controller.buttonPressed)
 | 
						|
        if (buttonFlags & Y_BUTTON) ~= 0 and weapon.primaryFireFunc ~= nil then
 | 
						|
            weapon.cooldownTimer = weapon.cooldownTime
 | 
						|
            weapon.primaryFireFunc(weapon)
 | 
						|
        elseif (buttonFlags & X_BUTTON) ~= 0 and weapon.secondaryFireFunc ~= nil then
 | 
						|
            weapon.cooldownTimer = weapon.cooldownTime
 | 
						|
            weapon.secondaryFireFunc(weapon)
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    weapon1.deployTimer = handle_timer(weapon1.deployTimer)
 | 
						|
    weapon1.cooldownTimer = handle_timer(weapon1.cooldownTimer)
 | 
						|
    if weapon2 ~= nil then
 | 
						|
        weapon2.deployTimer = handle_timer(weapon2.deployTimer)
 | 
						|
        weapon2.cooldownTimer = handle_timer(weapon2.cooldownTimer)
 | 
						|
    end
 | 
						|
    handle_reloading(weapon1)
 | 
						|
    handle_reloading(weapon2)
 | 
						|
end
 | 
						|
 | 
						|
function delete_held_weapon()
 | 
						|
    local held = obj_get_first_with_behavior_id(id_bhvHeldWeapon)
 | 
						|
    while held ~= nil do
 | 
						|
        if obj_get_weapon_owner(held) == gNetworkPlayers[0].globalIndex then
 | 
						|
            obj_mark_for_deletion(held)
 | 
						|
        end
 | 
						|
        held = obj_get_next_with_same_behavior_id(held)
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
 | 
						|
-------------
 | 
						|
-- objects --
 | 
						|
-------------
 | 
						|
 | 
						|
--- @param o Object
 | 
						|
local function bhv_held_weapon_init(o)
 | 
						|
    o.oFlags = OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE
 | 
						|
    o.oGraphYOffset = 10
 | 
						|
    cur_obj_scale(0.6)
 | 
						|
    cur_obj_hide()
 | 
						|
end
 | 
						|
 | 
						|
--- @param o Object
 | 
						|
local function bhv_held_weapon_loop(o)
 | 
						|
    local np = network_player_from_global_index(obj_get_weapon_owner(o))
 | 
						|
    if np == nil or not gGlobalSyncTable.gunModEnabled then
 | 
						|
        obj_mark_for_deletion(o)
 | 
						|
        return
 | 
						|
    end
 | 
						|
    local m = gMarioStates[np.localIndex]
 | 
						|
    local dualWield = obj_get_weapon_dual_wield(o)
 | 
						|
    --- @type Weapon|nil
 | 
						|
    local weapon = if_then_else(dualWield ~= 0, cur_dual_wield_weapon(), cur_weapon())
 | 
						|
    if active_player(m) == 0 or weapon == nil then
 | 
						|
        obj_mark_for_deletion(o)
 | 
						|
        return
 | 
						|
    end
 | 
						|
 | 
						|
    local index = if_then_else(dualWield ~= 0, 1, 0)
 | 
						|
    if m.marioBodyState.updateTorsoTime == gMarioStates[0].marioBodyState.updateTorsoTime and m.marioBodyState.handState == MARIO_HAND_FISTS and weapon.reqCheck(m) then
 | 
						|
        cur_obj_unhide()
 | 
						|
        o.oPosX = get_hand_foot_pos_x(m, index) + m.vel.x - (sins(m.faceAngle.y) * 30)
 | 
						|
        o.oPosY = get_hand_foot_pos_y(m, index) + m.vel.y + if_then_else(m.action == ACT_JUMP or m.action == ACT_DOUBLE_JUMP, 20, 0)
 | 
						|
        o.oPosZ = get_hand_foot_pos_z(m, index) + m.vel.z - (coss(m.faceAngle.y) * 30)
 | 
						|
        o.oFaceAngleYaw = m.faceAngle.y - 0x4000
 | 
						|
        o.oFaceAnglePitch = 0
 | 
						|
        o.oFaceAngleRoll = 0
 | 
						|
    else
 | 
						|
        cur_obj_hide()
 | 
						|
        o.oPosX = m.pos.x
 | 
						|
        o.oPosY = m.pos.y + 60
 | 
						|
        o.oPosZ = m.pos.z
 | 
						|
    end
 | 
						|
 | 
						|
    if m.playerIndex == 0 and get_first_person_enabled() then
 | 
						|
        cur_obj_hide()
 | 
						|
    end
 | 
						|
 | 
						|
    obj_set_model_extended(o, weapon.model)
 | 
						|
end
 | 
						|
 | 
						|
id_bhvHeldWeapon = hook_behavior(nil, OBJ_LIST_GENACTOR, true, bhv_held_weapon_init, bhv_held_weapon_loop, "bhvGmHeldWeapon")
 | 
						|
 | 
						|
 | 
						|
--- @param o Object
 | 
						|
local function bhv_pickup_weapon_init(o)
 | 
						|
    o.oFlags = OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE
 | 
						|
    o.oIntangibleTimer = 0
 | 
						|
    obj_scale(o, 0.75)
 | 
						|
 | 
						|
    o.hitboxRadius = 90
 | 
						|
    o.hitboxHeight = 90
 | 
						|
 | 
						|
    network_init_object(o, true, {})
 | 
						|
end
 | 
						|
 | 
						|
--- @param o Object
 | 
						|
local function bhv_pickup_weapon_loop(o)
 | 
						|
    cur_obj_update_floor_height()
 | 
						|
    o.oPosY = o.oFloorHeight + 130
 | 
						|
 | 
						|
    o.oFaceAngleYaw = o.oFaceAngleYaw + 0x800
 | 
						|
 | 
						|
    local nearest = nearest_mario_state_to_object(o)
 | 
						|
    if obj_check_hitbox_overlap(o, nearest.marioObj) and o.oIntangibleTimer == 0 and nearest.playerIndex == 0 then
 | 
						|
        o.oIntangibleTimer = 450
 | 
						|
        pickup_weapon(o.oBehParams)
 | 
						|
    end
 | 
						|
 | 
						|
    if o.oIntangibleTimer ~= 0 then
 | 
						|
        cur_obj_hide()
 | 
						|
    else
 | 
						|
        cur_obj_unhide()
 | 
						|
        o.oGraphYOffset = math.sin(o.oTimer * 0.5) * 5
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
id_bhvWeaponPickup = hook_behavior(nil, OBJ_LIST_LEVEL, true, bhv_pickup_weapon_init, bhv_pickup_weapon_loop, "bhvGmWeaponPickup")
 | 
						|
 | 
						|
 | 
						|
-------------
 | 
						|
-- weapons --
 | 
						|
-------------
 | 
						|
 | 
						|
WEAPON_PISTOL = weapon_register(
 | 
						|
    "Pistol", -- name
 | 
						|
    true, -- dual wieldable
 | 
						|
    E_MODEL_PISTOL, -- weapon model
 | 
						|
    E_MODEL_SINGLE_ARM, -- arm model
 | 
						|
    E_MODEL_YELLOW_COIN, -- bullet model
 | 
						|
    { sync_audio_sample_load("pistol_shoot.mp3") }, -- primary sounds
 | 
						|
    { sync_audio_sample_load("pistol_reload.mp3") }, -- secondary sounds
 | 
						|
    false, -- strong weapon
 | 
						|
    false, -- rapid fire
 | 
						|
    10, -- spread
 | 
						|
    15, -- damage
 | 
						|
    1, -- bullet count
 | 
						|
    0.2, -- bullet scale
 | 
						|
    500, -- bullet speed
 | 
						|
    10, -- bullet steps
 | 
						|
    18, -- max ammo
 | 
						|
    15, -- deploy time
 | 
						|
    5, -- cooldown time
 | 
						|
    60, -- reload time
 | 
						|
    common_shoot, -- primary fire
 | 
						|
    common_reload, -- secondary fire
 | 
						|
    check_common_gun_requirements -- requirement checks function
 | 
						|
)
 | 
						|
 | 
						|
WEAPON_MAGNUM = weapon_register(
 | 
						|
    "Magnum", -- name
 | 
						|
    true, -- dual wieldable
 | 
						|
    E_MODEL_MAGNUM, -- weapon model
 | 
						|
    E_MODEL_SINGLE_ARM, -- arm model
 | 
						|
    E_MODEL_METALLIC_BALL, -- bullet model
 | 
						|
    { sync_audio_sample_load("magnum_shoot.mp3") }, -- primary sounds
 | 
						|
    { sync_audio_sample_load("magnum_reload.mp3") }, -- secondary sounds
 | 
						|
    false, -- strong weapon
 | 
						|
    false, -- rapid fire
 | 
						|
    0, -- spread
 | 
						|
    50, -- damage
 | 
						|
    1, -- bullet count
 | 
						|
    0.2, -- bullet scale
 | 
						|
    2000, -- bullet speed
 | 
						|
    40, -- bullet steps
 | 
						|
    6, -- max ammo
 | 
						|
    15, -- deploy time
 | 
						|
    30, -- cooldown time
 | 
						|
    90, -- reload time
 | 
						|
    common_shoot, -- primary fire
 | 
						|
    common_reload, -- secondary fire
 | 
						|
    check_common_gun_requirements -- requirement checks function
 | 
						|
)
 | 
						|
 | 
						|
WEAPON_AK47 = weapon_register(
 | 
						|
    "AK47", -- name
 | 
						|
    false, -- dual wieldable
 | 
						|
    E_MODEL_AK47, -- weapon model
 | 
						|
    E_MODEL_SINGLE_ARM, -- arm model
 | 
						|
    E_MODEL_YELLOW_COIN, -- bullet model
 | 
						|
    { sync_audio_sample_load("ak47_shoot.mp3") }, -- primary sounds
 | 
						|
    { sync_audio_sample_load("pistol_reload.mp3") }, -- secondary sounds
 | 
						|
    false, -- strong weapon
 | 
						|
    true, -- rapid fire
 | 
						|
    30, -- spread
 | 
						|
    10, -- damage
 | 
						|
    1, -- bullet count
 | 
						|
    0.2, -- bullet scale
 | 
						|
    500, -- bullet speed
 | 
						|
    10, -- bullet steps
 | 
						|
    40, -- max ammo
 | 
						|
    30, -- deploy time
 | 
						|
    4, -- cooldown time
 | 
						|
    70, -- reload time
 | 
						|
    common_shoot, -- primary fire
 | 
						|
    common_reload, -- secondary fire
 | 
						|
    check_common_gun_requirements -- requirement checks function
 | 
						|
)
 | 
						|
 | 
						|
--[[WEAPON_SHOTGUN = weapon_register(
 | 
						|
    "Shotgun", -- name
 | 
						|
    false, -- dual wieldable
 | 
						|
    E_MODEL_SHOTGUN, -- weapon model
 | 
						|
    E_MODEL_SINGLE_ARM, -- arm model
 | 
						|
    E_MODEL_RED_COIN, -- bullet model
 | 
						|
    { sync_audio_sample_load("shotgun_shoot.mp3") }, -- primary sounds
 | 
						|
    {}, -- secondary sounds
 | 
						|
    true, -- strong weapon
 | 
						|
    false, -- rapid fire
 | 
						|
    50, -- spread
 | 
						|
    6, -- damage
 | 
						|
    5, -- bullet count
 | 
						|
    0.2, -- bullet scale
 | 
						|
    1000, -- bullet speed
 | 
						|
    20, -- bullet steps
 | 
						|
    7, -- max ammo
 | 
						|
    15, -- deploy time
 | 
						|
    30, -- cooldown time
 | 
						|
    120, -- reload time
 | 
						|
    common_shoot, -- primary fire
 | 
						|
    common_reload, -- secondary fire
 | 
						|
    check_common_gun_requirements -- requirement checks function
 | 
						|
)]] |