CityRP Documentation Repository

Maintenance Work System

Last updated

The Maintenance Work System adds periodic maintenance tasks to entities around the city, providing a new avenue for income and making the server feel more alive. Entities randomly break down and require player intervention to repair.

Overview

The maintenance system works by:

  1. Scanning the map for entities that support maintenance
  2. Randomly selecting entities to trigger maintenance events on
  3. Displaying active maintenance jobs to players via HUD
  4. Allowing players to fix maintenance issues for a reward

Configuration

The maintenance plugin can be configured in sh_init.lua:

PLUGIN.config["Maintenance Timer"] = 300       -- Delay in seconds between triggering new maintenance events
PLUGIN.config["Max Maintenance Jobs"] = 3      -- Maximum number of active maintenance jobs at once
PLUGIN.config["Reward Fee"] = 1000             -- Amount to pay player for fixing maintenance issues
PLUGIN.config["Fix Distance"] = 200            -- Maximum distance in units to fix a maintenance issue
PLUGIN.config["Fix Cooldown"] = 300            -- Cooldown in seconds before an entity can break again after being fixed

Maintenance Event Types

The system supports several maintenance event types:

Type Status Description
Electronic Active Electronics fault with sparking visual effects
Water Active Water leak with visual spray effects (area-based)
Petrol Active Petrol leak with visual drip effects (area-based)
Gas Active Gas leak with visual cloud effects (area-based)
Restock Not Used Entity needs restocking (deprecated)
Destock Active Vending machine expired stock; dispose trash bag for payout

Electronic Maintenance

Entities with electronic faults display sparking effects and become non-functional until repaired.

Supported Entities:

  • Phonebooths (cityrp_phonebooth)
  • Vending Machines (cityrp_nommachine)
  • Tesla Superchargers (cityrp_tesla_supercharger)
  • Lift electrical boxes (map buttons)

Water Maintenance

Area-based water leaks that display water spray effects. Created by admins at specific map locations.

Status: Active (area-based)

Petrol Maintenance

Area-based petrol leaks that display drip effects. Created by admins at specific map locations.

Status: Active (area-based)

Gas Maintenance

Area-based gas leaks that display cloud effects. Created by admins at specific map locations.

Status: Active (area-based)

Destock Maintenance

Vending machines occasionally need expired products removed. Destocking is a two-step job:

  1. A maintenance worker uses the machine (+use) to clear the maintenance flag and spawn a cityrp_trashbag
  2. The trash bag must be placed in a cityrp_rubbish_bin to claim the reward payout

Clearing the machine restores normal use immediately — the worker does not need to finish the disposal step for the machine to work again. Payment is only granted when the bag is deposited. If a trash bag is abandoned, any player can pick it up and dispose of it for the reward.

Supported Entities:

  • Vending Machines (cityrp_nommachine) — randomly Electric or Destock when a job triggers

Testing: maintforce destock

Area-Based Maintenance Points

Water, Petrol, and Gas maintenance are area-based and require admin setup. These are positions on the map where leaks can randomly occur.

Admin Commands

Add a maintenance point:

/maintpoint add <type>

Types: water, petrol, gas

Looks at where you're aiming and adds a maintenance point of the specified type.

Remove nearby maintenance points:

/maintpoint remove

Removes all maintenance points within 256 units of where you're aiming.

List maintenance points:

/maintpoint list

Shows total count and breakdown by type for the current map.

Save maintenance points:

/maintpoint save

Saves all maintenance points to the data folder. Points are automatically loaded on map start.

Maintenance Point Storage

Points are saved per-map in:

garrysmod/data/cityrp/plugins/maintenance/<mapname>.txt

The file is automatically created when you save points.

Adding Maintenance Support to Entities

To add maintenance support to a new entity:

1. Register the Entity Class

Add the entity class to maintenanceEntClasses in sh_init.lua:

PLUGIN.tab.maintenanceEntClasses = {
    ["ent_phonebooth"] = "Electronic",
    ["cityrp_nommachine"] = "Restock",
    ["your_entity_class"] = "Electronic", -- Your new entity
}

2. Initialize Maintenance in Entity

In your entity's Initialize function (server-side):

function ENT:Initialize()
    -- ... your existing initialization code ...
    
    local maintenancePlugin = cityrp.plugin.get("maintenance")
    if maintenancePlugin then
        self.maintenance = maintenancePlugin.electric  -- or .restock
        self.maintenance.disabled = false  -- for electric
        -- OR
        self.maintenance.needsRestock = false  -- for restock
    end
end

3. Check Maintenance Status in Use Function

In your entity's Use function (server-side):

function ENT:Use(activator, caller)
    -- Check if entity needs maintenance
    if self.maintenance and self.maintenance.disabled then
        activator:Notify("This entity is broken! Perhaps a mechanic could fix it?", NOTIFY_ERROR)
        return
    end
    
    -- OR for restock type:
    if self.maintenance and self.maintenance.needsRestock then
        activator:Notify("This entity needs restocking!", NOTIFY_ERROR)
        return
    end
    
    -- ... rest of your use logic ...
end

4. Add Client-Side Hints (Optional)

In your entity's DrawTargetHUD function (client-side):

function ENT:DrawTargetHUD(x, y, alpha)
    y = GAMEMODE:DrawInformation(self.PrintName, FONT_TARGETID_HEAD, x, y, COL_BRAND, alpha)
    
    if self.maintenance and self.maintenance.disabled then
        if cityrp.hints:Get("maintenance_work") then
            y = GAMEMODE:DrawInformation("This entity is broken. Use ␂maintfix␃ to repair it.", FONT_TARGETID, x, y, Color(255, 150, 0, alpha), alpha)
        else
            y = GAMEMODE:DrawInformation("This entity is broken.", FONT_TARGETID, x, y, Color(255, 150, 0, alpha), alpha)
        end
    elseif cityrp.hints:Get("entities") then
        y = GAMEMODE:DrawInformation("Press ␂+use␃ to interact.", FONT_TARGETID, x, y, COL_GUIDE, alpha)
    end
end

Creating New Maintenance Types

To create a new maintenance type:

  1. Create a new file in the maintenance plugin directory (e.g., sh_water.lua)
  2. Define the maintenance type behavior:
---@state shared
local PLUGIN = PLUGIN_SHARED

PLUGIN.water = {}

---Trigger water maintenance on an entity
---@param e Entity The entity to trigger maintenance on
function PLUGIN.water:triggerMaintenance(e)
    self.leaking = true
    
    -- Add visual effects here (e.g., water spray particle effect)
end

---Fix water maintenance on an entity
---@param e Entity The entity to fix
---@param ply Player The player fixing the entity
function PLUGIN.water:fixMaintenance(e, ply)
    self.leaking = false
    
    ply:Notify("You fixed the water leak and earned $" .. string.Comma(PLUGIN.config["Reward Fee"]) .. "!", NOTIFY_HINT)
    ply:GiveMoney(PLUGIN.config["Reward Fee"])
    
    PLUGIN.tab.activeJobs[e] = nil
end
  1. Include the file in sv_init.lua:
include("sh_water.lua")
AddCSLuaFile("sh_water.lua")
  1. Update entity classes to use the new type in sh_init.lua:
PLUGIN.tab.maintenanceEntClasses = {
    ["your_entity"] = "Water",
}

Player Commands

Players use the Mechanic Wrench SWEP to fix maintenance issues. Simply equip the wrench and left-click while aiming at a broken entity or standing near an area-based leak.

User Interface

Active Jobs HUD

Active maintenance jobs are displayed in the top-right corner of the screen, showing:

  • A header "Maintenance Jobs"
  • List of entities that need maintenance

Entity Hints

When looking at an entity that needs maintenance:

  • Entity displays its broken status
  • If hints are enabled, shows the command to fix it (maintfix)

Hints System Integration

The maintenance system integrates with CityRP's hints system under the "Maintenance Work" category. Players can toggle maintenance hints in Options > Limelight > Hints.

System Behavior

  1. Entity Indexing: On server start, the system indexes all entities on the map that support maintenance
  2. Point Loading: Area-based maintenance points are loaded from the data folder for the current map
  3. Periodic Triggering: Every 300 seconds (configurable), the system checks if new maintenance events should be triggered
  4. Max Jobs: The system maintains up to 3 active maintenance jobs at once (configurable), combining both entity-based and area-based jobs
  5. Job Selection: Jobs are randomly selected from both entity and area-based pools. Vending machines randomly choose Electric or Destock.
  6. Cooldowns: After an entity is fixed, it goes on a 5-minute cooldown (configurable) before it can break again
  7. Client Sync: Active jobs are synchronized to all clients for HUD display
  8. Distance Check: Players must be within 200 units (configurable) of an entity or leak to fix it

Future Enhancements

Planned features for future releases:

  • Job-restricted maintenance (require specific jobs to fix certain types)
  • Specialized tools or equipment requirements
  • Difficulty-based rewards
  • Integration with vehicle systems
  • Damage effects for gas leaks