Skip to main content

Players

Namespace: DeadworksManaged.Api

The player system consists of controllers (managing the player slot) and pawns (the in-game physical entity).

Players (Static Helpers)

// Get all connected controllers
foreach (var controller in Players.GetAll()) { }

// Get all hero pawns
foreach (var pawn in Players.GetAllPawns()) { }

// Get controller by slot
var controller = Players.FromSlot(slotIndex);
MemberTypeDescription
MaxSlotsint (const)Maximum number of player slots on the server
GetAll()IEnumerable<CCitadelPlayerController>All connected controllers
GetAllPawns()IEnumerable<CCitadelPlayerPawn>Hero pawn for every connected player that has one
FromSlot(int)CCitadelPlayerController?Controller in given slot, or null

CCitadelPlayerController

Deadlock-specific player controller. Extends CBasePlayerController.

Methods

MethodReturnsDescription
GetHeroPawn()CCitadelPlayerPawn?Returns the player's current hero pawn, or null
ChangeTeam(int team)voidMoves player to specified team
SelectHero(Heroes hero)voidForces player to select specified hero
PrintToConsole(string msg)voidSends message to this player's console
PrintToConsoleAll(string msg)voidSends message to all connected players' consoles

Properties

PropertyTypeDescription
PlayerDataGlobalPlayerDataGlobal?Read-only access to networked stats (kills, gold, level, damage)

Example

var controller = ctx.Controller;
if (controller == null) return HookResult.Handled;

// Force hero selection
controller.SelectHero(Heroes.Inferno);

// Change team
controller.ChangeTeam(2);

// Get pawn
var pawn = controller.GetHeroPawn();

CBasePlayerController

Base player controller entity. Manages the link between a player slot and their pawn.

MethodDescription
SetPawn(CBasePlayerPawn, bool, bool, bool, bool)Assigns a new pawn, optionally transferring team and movement state

CCitadelPlayerPawn

The in-game physical representation of a player (the hero). Extends CBasePlayerPawn.

Properties

PropertyTypeDescription
EyeAnglesVector3Networked eye angles (quantized to 11 bits, ~0.18° precision)
EyePositionVector3Eye position (AbsOrigin + ViewOffset) — where the camera sits
CameraAnglesVector3Client camera angles for SourceTV/spectating
ViewAnglesVector3Raw server-side view angles (full float precision, no quantization)
HealthintCurrent health (inherited from CBaseEntity)
PositionVector3World position (inherited from CBaseEntity)
Angles & Position — All Confirmed Working (Read)
  • Position — World-space origin of the pawn (feet)
  • EyePosition — Where the camera sits (origin + view offset, ~72 units above position)
  • EyeAngles — Quantized eye angles (~0.18° precision, suitable for most checks)
  • ViewAngles — Full-precision server-side view angles (use for accurate aim calculations)
  • CameraAngles — Client camera angles (useful for spectating/SourceTV)
  • Velocity — Use m_vecVelocity / m_vecAbsVelocity via SchemaAccessor<Vector3> (see Entities — Velocity)
  • Setting camera — Use CCitadelUserMsg_SetClientCameraAngles via NetMessages.Send (see Networking). Schema writes and Teleport angles only move the model, not the camera.
  • Camera offset — The third-person camera sits ~35 units to the right of EyePosition (right shoulder view). Account for this when calculating aim angles.

| AbilityComponent | CCitadelAbilityComponent | Access to stamina and ability resources | | ModifierProp | CModifierProperty | Access to modifier state flags |

Methods

MethodReturnsDescription
ModifyCurrency(ECurrencyType, int, ECurrencySource, bool, bool, bool)voidAdd/remove currency (gold, ability points). Negative to spend
ResetHero(bool)voidFull reset: clears loadout, removes items, re-adds starting abilities
RemoveAbility(string name)boolRemoves ability by internal name. Returns true on success
AddAbility(string name, uint slot)CBaseEntity?Adds ability to given slot. Returns the new ability entity

Currency Example

// Give 15000 gold
pawn.ModifyCurrency(ECurrencyType.Gold, 15000, ECurrencySource.FlagCapture, false, false, false);

// Give 17 ability points
pawn.ModifyCurrency(ECurrencyType.AbilityPoints, 17, ECurrencySource.FlagCapture, false, false, false);

Ability Management

// Remove an ability
pawn.RemoveAbility("ability_priest_weaponswap");

// Add an ability to slot 3
pawn.AddAbility("ability_familiar_ability01", slot: 3);

EAbilitySlots_t

ValueRawDescription
ESlot_Signature_10Signature ability 1
ESlot_Signature_21Signature ability 2
ESlot_Signature_32Signature ability 3
ESlot_Signature_43Signature ability 4 (ultimate)
ESlot_ActiveItem_14Active item slot 1
ESlot_ActiveItem_25Active item slot 2
ESlot_ActiveItem_36Active item slot 3
ESlot_ActiveItem_47Active item slot 4
ESlot_Ability_Held8Held ability
ESlot_Ability_ZipLine9Zipline ability
ESlot_Ability_Mantle10Mantle ability
ESlot_Ability_ClimbRope11Climb rope ability
ESlot_Ability_Jump12Jump ability
ESlot_Ability_Slide13Slide ability
ESlot_Ability_Teleport14Teleport ability
ESlot_Ability_ZipLineBoost15Zipline boost
ESlot_Ability_Innate_117Innate ability 1
ESlot_Ability_Innate_218Innate ability 2
ESlot_Ability_Innate_319Innate ability 3
ESlot_Weapon_Secondary20Secondary weapon
ESlot_Weapon_Primary21Primary weapon
ESlot_Weapon_Melee22Melee weapon
ESlot_None23No slot
note

AddAbility only works for item abilities (EAbilityType_Item). The slot parameter corresponds to these values. Item abilities typically use slots 4-7.

CCitadelAbilityComponent

Ability component on a player pawn. Provides access to stamina/ability resources.

ResourceStamina (AbilityResource)

var stamina = pawn.AbilityComponent.ResourceStamina;

// Read values (confirmed working)
float current = stamina.CurrentValue; // e.g. 3
float max = stamina.MaxValue; // e.g. 3
float regen = stamina.PrevRegenRate; // e.g. 0.555555
float latch = stamina.LatchTime; // server time of last latch
float latchVal = stamina.LatchValue; // e.g. 3
PropertyTypeReadWriteDescription
CurrentValuefloatYesNoCurrent stamina value. Writing is overridden by the engine next tick
MaxValuefloatYesNoMaximum stamina value
PrevRegenRatefloatYesNoStamina regeneration rate per second
LatchTimefloatYesNoServer time of last latch event
LatchValuefloatYesNoLatch value
Stamina Write Does Not Work

While CurrentValue has a setter, the engine's native stamina system recalculates the value every tick, immediately overriding any managed-side writes. Use modifiers or abilities to affect stamina instead.

Ability Entities

CCitadel_Ability_Jump

Jump ability entity tracking air jump/wall jump counters. Cast from the abilities list with As<CCitadel_Ability_Jump>().

PropertyTypeDescription
DesiredAirJumpCountintTarget air jump count
ExecutedAirJumpCountintActual air jumps performed
ConsecutiveAirJumpssbyteConsecutive air jumps without landing
ConsecutiveWallJumpssbyteConsecutive wall jumps

CCitadel_Ability_Dash

Dash ability entity tracking consecutive air/down dash counters. Cast with As<CCitadel_Ability_Dash>().

PropertyTypeDescription
ConsecutiveAirDashessbyteConsecutive air dashes without landing
ConsecutiveDownDashessbyteConsecutive downward dashes

Example: Reading Ability Counters

var abilities = pawn.AbilityComponent.Abilities;
for (int i = 0; i < abilities.Count; i++)
{
var jump = abilities[i].As<CCitadel_Ability_Jump>();
if (jump != null)
Console.WriteLine($"Air jumps: {jump.ConsecutiveAirJumps}");

var dash = abilities[i].As<CCitadel_Ability_Dash>();
if (dash != null)
Console.WriteLine($"Air dashes: {dash.ConsecutiveAirDashes}");
}

PlayerDataGlobal

Read-only access to networked player stats via Controller.PlayerDataGlobal.

The underlying schema type is PlayerDataGlobal_t. You can read fields via SchemaAccessor<T> on the controller's handle:

private static readonly SchemaAccessor<int> _goldNetWorth =
new("PlayerDataGlobal_t"u8, "m_iGoldNetWorth"u8);
private static readonly SchemaAccessor<int> _playerKills =
new("PlayerDataGlobal_t"u8, "m_iPlayerKills"u8);
private static readonly SchemaAccessor<int> _heroDamage =
new("PlayerDataGlobal_t"u8, "m_iHeroDamage"u8);

// Read from the controller
var controller = Players.FromSlot(slot);
int networth = _goldNetWorth.Get(controller.Handle);
int kills = _playerKills.Get(controller.Handle);
int damage = _heroDamage.Get(controller.Handle);

All Fields (Verified)

All 24 fields confirmed readable via test:

PropertyTypeDescription
LevelintHero level
MaxAmmointMaximum ammo count
HealthMaxintMaximum health
HealthintCurrent health
GoldNetWorthintTotal gold (souls) networth
APNetWorthintAbility point networth
CreepGoldintTotal creep gold earned
CreepGoldSoloBonusintSolo lane bonus gold
CreepGoldKillintGold from creep last hits
CreepGoldAirOrbintGold from air orbs
CreepGoldGroundOrbintGold from ground orbs
CreepGoldDenyintGold from denies
CreepGoldNeutralintGold from neutral camps
FarmBaselineintFarm baseline value
PlayerKillsintPlayer kills
PlayerAssistsintPlayer assists
DeathsintDeaths
DeniesintCreep denies
LastHitsintCreep last hits
KillStreakintCurrent kill streak
HeroDraftPositionintPosition in hero draft
HeroDamageintTotal hero damage dealt
HeroHealingintHero healing done
SelfHealingintSelf healing done
ObjectiveDamageintDamage dealt to objectives

These can also be read via SchemaAccessor<int> on the controller handle using "PlayerDataGlobal_t" as the class name (e.g. "m_iGoldNetWorth").

Slot Limit

Player slots above 31 contain garbage data (e.g. Level=1119879168). Always cap iteration to slot < 32 when reading PlayerDataGlobal fields across all players.

Action Detection Limitations

The API provides limited ability to detect what players are doing. This affects what kinds of triggers and conditions you can build.

Can detect:

  • Stamina changes (indicates jump/dash via AbilityComponent.ResourceStamina)
  • Position changes (via Position, EyePosition)
  • View angle changes (via ViewAngles, EyeAngles)
  • Health changes (via Health, OnTakeDamage hook)
  • Death and respawn (via LifeState, game events)
  • Currency changes (via OnModifyCurrency hook)
  • Chat messages and console commands

Cannot detect:

  • Ability use (no ability-cast event or hook)
  • Ultimate activation
  • Item activation
  • Reload
  • Melee attack / parry
  • Crouch
  • Mantle
Workaround

For jump/dash detection, poll AbilityComponent.ResourceStamina.CurrentValue every tick — a decrease indicates a stamina-consuming action was performed.

Currency Types

ECurrencyType

ValueRawDescription
Invalid-1Invalid
Gold0In-game gold (souls)
AbilityPoints1Ability upgrade points
AbilityUnlocks2Ability unlock tokens
DeathPenaltyGold3Gold lost on death
ItemDraftRerolls4Item draft reroll tokens
ItemEnhancements5Item enhancement tokens

ECurrencySource

ValueRawDescription
EItemPurchase0Item purchased
EItemSale2Item sold
ECheats7Cheat/debug
EPlayerKill11Player kill reward
EPlayerKillAssist12Assist reward
EBossKill13Boss kill reward
ELaneTrooperKill14Lane trooper kill
ENeutralTrooperKill15Neutral camp kill
EOrbPlayer23Soul orb from player
EOrbLaneTrooper25Soul orb from lane trooper
note

ECurrencySource has 45 values total. Only the most commonly used are listed above.

LifeState

Entity life-cycle state (LifeState_t):

ValueRawDescription
LIFE_ALIVE0Entity is alive
LIFE_DYING1Entity is in the dying process
LIFE_DEAD2Entity is dead
LIFE_RESPAWNABLE3Entity can respawn
LIFE_RESPAWNING4Entity is respawning

See Also