Skip to content

Exposing detailed knife details #431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
105 changes: 83 additions & 22 deletions pkg/demoinfocs/common/equipment.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,25 @@ const (
EqWrench EquipmentType = 419
EqSnowball EquipmentType = 420
EqBumpMine EquipmentType = 421
EqKnifeBayonet EquipmentType = 422
EqKnifeCSS EquipmentType = 423
EqKnifeFlip EquipmentType = 424
EqKnifeGut EquipmentType = 425
EqKnifeKarambit EquipmentType = 426
EqKnifeM9Bayonet EquipmentType = 427
EqKnifeTactical EquipmentType = 428
EqKnifeFalchion EquipmentType = 429
EqKnifeSurvivalBowie EquipmentType = 430
EqKnifeButterfly EquipmentType = 431
EqKnifePush EquipmentType = 432
EqKnifeCord EquipmentType = 433
EqKnifeCanis EquipmentType = 434
EqKnifeUrsus EquipmentType = 435
EqKnifeGypsyJackknife EquipmentType = 436
EqKnifeOutdoor EquipmentType = 437
EqKnifeStiletto EquipmentType = 438
EqKnifeWidowmaker EquipmentType = 439
EqKnifeSkeleton EquipmentType = 440
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the RawEquipment part looks good now - but this part will need to be removed as it's not backwards compatible as mentioned in the other thread.

So all we should do for now is expose RawEquipment.

Maybe we can have a separate type KnifeType and constants KnifeTypeXYZ with a map KnifeTypes map[string]KnifeType which includes all known knife types to still provide some kind of mapping.

The good thing about this is that if a new knife comes out the users can just add it to the map themselves,. as the map will be mutable.

I think this would be the best middleground


// Grenades

Expand Down Expand Up @@ -204,6 +223,28 @@ func initEqNameToWeapon() {
eqNameToWeapon["vesthelm"] = EqHelmet
eqNameToWeapon["defuser"] = EqDefuseKit

eqNameToWeapon["knife"] = EqKnife
eqNameToWeapon["bayonet"] = EqKnifeBayonet
eqNameToWeapon["knife_bayonet"] = EqKnifeBayonet
eqNameToWeapon["knife_css"] = EqKnifeCSS
eqNameToWeapon["knife_flip"] = EqKnifeFlip
eqNameToWeapon["knife_gut"] = EqKnifeGut
eqNameToWeapon["knife_karambit"] = EqKnifeKarambit
eqNameToWeapon["knife_m9_bayonet"] = EqKnifeM9Bayonet
eqNameToWeapon["knife_tactical"] = EqKnifeTactical
eqNameToWeapon["knife_falchion"] = EqKnifeFalchion
eqNameToWeapon["knife_survival_bowie"] = EqKnifeSurvivalBowie
eqNameToWeapon["knife_butterfly"] = EqKnifeButterfly
eqNameToWeapon["knife_push"] = EqKnifePush
eqNameToWeapon["knife_cord"] = EqKnifeCord
eqNameToWeapon["knife_canis"] = EqKnifeCanis
eqNameToWeapon["knife_ursus"] = EqKnifeUrsus
eqNameToWeapon["knife_gypsy_jackknife"] = EqKnifeGypsyJackknife
eqNameToWeapon["knife_outdoor"] = EqKnifeOutdoor
eqNameToWeapon["knife_stiletto"] = EqKnifeStiletto
eqNameToWeapon["knife_widowmaker"] = EqKnifeWidowmaker
eqNameToWeapon["knife_skeleton"] = EqKnifeSkeleton
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, would need to be moved to the new map I wrote about


// These don't exist and / or used to crash the game with the give command
eqNameToWeapon["scar17"] = EqUnknown
eqNameToWeapon["sensorgrenade"] = EqUnknown
Expand Down Expand Up @@ -267,6 +308,25 @@ func initEqElementToName() {
eqElementToName[EqDefuseKit] = "Defuse Kit"
eqElementToName[EqKnife] = "Knife"
eqElementToName[EqUnknown] = "UNKNOWN"
eqElementToName[EqKnifeBayonet] = "Bayonet"
eqElementToName[EqKnifeCSS] = "CSS Knife"
eqElementToName[EqKnifeFlip] = "Flip Knife"
eqElementToName[EqKnifeGut] = "Gut Knife"
eqElementToName[EqKnifeKarambit] = "Karambit"
eqElementToName[EqKnifeM9Bayonet] = "M9 Bayonet"
eqElementToName[EqKnifeTactical] = "Tactical Knife"
eqElementToName[EqKnifeFalchion] = "Falchion Knife"
eqElementToName[EqKnifeSurvivalBowie] = "Survival Bowie Knife"
eqElementToName[EqKnifeButterfly] = "Butterfly Knife"
eqElementToName[EqKnifePush] = "Push Knife"
eqElementToName[EqKnifeCord] = "Cord Knife"
eqElementToName[EqKnifeCanis] = "Canis Knife"
eqElementToName[EqKnifeUrsus] = "Ursus Knife"
eqElementToName[EqKnifeGypsyJackknife] = "Gypsy Jackknife"
eqElementToName[EqKnifeOutdoor] = "Outdoor Knife"
eqElementToName[EqKnifeStiletto] = "Stiletto Knife"
eqElementToName[EqKnifeWidowmaker] = "Widowmaker Knife"
eqElementToName[EqKnifeSkeleton] = "Skeleton Knife"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this would have to be in a new map knifeTypeToName - don't forget to implement the String() method on KnifeType

}

const weaponPrefix = "weapon_"
Expand Down Expand Up @@ -300,9 +360,10 @@ const (
// Equipment is a weapon / piece of equipment belonging to a player.
// This also includes the skin and some additional data.
type Equipment struct {
Type EquipmentType // The type of weapon which the equipment instantiates.
Entity st.Entity // The game entity instance
Owner *Player // The player carrying the equipment, not necessarily the buyer.
Type EquipmentType // The type of weapon which the equipment instantiates.
Entity st.Entity // The game entity instance
Owner *Player // The player carrying the equipment, not necessarily the buyer.
RawEquipment EquipmentType // More information about the equipment eq. the different knives.
// E.g. 'models/weapons/w_rif_m4a1_s.mdl'.
// Used internally to differentiate alternative weapons (M4A4 / M4A1-S etc.) for Source 1 demos.
// It's always an empty string with Source 2 demos, you should use Type to know which weapon it is.
Expand Down Expand Up @@ -543,23 +604,23 @@ var EquipmentIndexMapping = map[uint64]EquipmentType{
83: EqHE, // weapon_frag_grenade
84: EqSnowball, // weapon_snowball
85: EqBumpMine, // weapon_bumpmine
500: EqKnife, // weapon_bayonet
503: EqKnife, // weapon_knife_css
505: EqKnife, // weapon_knife_flip
506: EqKnife, // weapon_knife_gut
507: EqKnife, // weapon_knife_karambit
508: EqKnife, // weapon_knife_m9_bayonet
509: EqKnife, // weapon_knife_tactical
512: EqKnife, // weapon_knife_falchion
514: EqKnife, // weapon_knife_survival_bowie
515: EqKnife, // weapon_knife_butterfly
516: EqKnife, // weapon_knife_push
517: EqKnife, // weapon_knife_cord
518: EqKnife, // weapon_knife_canis
519: EqKnife, // weapon_knife_ursus
520: EqKnife, // weapon_knife_gypsy_jackknife
521: EqKnife, // weapon_knife_outdoor
522: EqKnife, // weapon_knife_stiletto
523: EqKnife, // weapon_knife_widowmaker
525: EqKnife, // weapon_knife_skeleton
500: EqKnifeBayonet, // weapon_bayonet
503: EqKnifeCSS, // weapon_knife_css
505: EqKnifeFlip, // weapon_knife_flip
506: EqKnifeGut, // weapon_knife_gut
507: EqKnifeKarambit, // weapon_knife_karambit
508: EqKnifeM9Bayonet, // weapon_knife_m9_bayonet
509: EqKnifeTactical, // weapon_knife_tactical
512: EqKnifeFalchion, // weapon_knife_falchion
514: EqKnifeSurvivalBowie, // weapon_knife_survival_bowie
515: EqKnifeButterfly, // weapon_knife_butterfly
516: EqKnifePush, // weapon_knife_push
517: EqKnifeCord, // weapon_knife_cord
518: EqKnifeCanis, // weapon_knife_canis
519: EqKnifeUrsus, // weapon_knife_ursus
520: EqKnifeGypsyJackknife, // weapon_knife_gypsy_jackknife
521: EqKnifeOutdoor, // weapon_knife_outdoor
522: EqKnifeStiletto, // weapon_knife_stiletto
523: EqKnifeWidowmaker, // weapon_knife_widowmaker
525: EqKnifeSkeleton, // weapon_knife_skeleton
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these would need to be put in a new map as well KnifeTypeIndexMapping

}
26 changes: 24 additions & 2 deletions pkg/demoinfocs/common/equipment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,35 @@ func TestEquipmentElement_Name(t *testing.T) {
}

func TestMapEquipment(t *testing.T) {
assert.Equal(t, EqKnife, MapEquipment("weapon_bayonet"), "'weapon_bayonet' should be mapped to EqKnife")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_butterfly"), "'weapon_knife_butterfly' should be mapped to EqKnife")
assert.Equal(t, EqKnife, MapEquipment("weapon_bayonet"), "'weapon_bayonet' should be mapped to EqKnifeBayonet")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_butterfly"), "'weapon_knife_butterfly' should be mapped to EqKnifeButterfly")
assert.Equal(t, EqM4A4, MapEquipment("weapon_m4a1"), "'weapon_m4a1' should be mapped to EqM4A4") // This is correct, weapon_m4a1 == M4A4
assert.Equal(t, EqM4A1, MapEquipment("weapon_m4a1_silencer"), "'weapon_m4a1_silencer' should be mapped to EqM4A1")
assert.Equal(t, EqUnknown, MapEquipment("asdf"), "'asdf' should be mapped to EqUnknown")
}

func TestMapEquipmentKnives(t *testing.T) {
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_bayonet"), "'weapon_knife_bayonet' should be mapped to EqKnifeBayonet")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_css"), "'weapon_knife_css' should be mapped to EqKnifeCSS")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_flip"), "'weapon_knife_flip' should be mapped to EqKnifeFlip")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_gut"), "'weapon_knife_gut' should be mapped to EqKnifeGut")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_karambit"), "'weapon_knife_karambit' should be mapped to EqKnifeKarambit")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_m9_bayonet"), "'weapon_knife_m9_bayonet' should be mapped to EqKnifeM9Bayonet")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_tactical"), "'weapon_knife_tactical' should be mapped to EqKnifeTactical")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_falchion"), "'weapon_knife_falchion' should be mapped to EqKnifeFalchion")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_survival_bowie"), "'weapon_knife_survival_bowie' should be mapped to EqKnifeSurvivalBowie")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_butterfly"), "'weapon_knife_butterfly' should be mapped to EqKnifeButterfly")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_push"), "'weapon_knife_push' should be mapped to EqKnifePush")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_cord"), "'weapon_knife_cord' should be mapped to EqKnifeCord")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_canis"), "'weapon_knife_canis' should be mapped to EqKnifeCanis")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_ursus"), "'weapon_knife_ursus' should be mapped to EqKnifeUrsus")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_gypsy_jackknife"), "'weapon_knife_gypsy_jackknife' should be mapped to EqKnifeGypsyJackknife")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_outdoor"), "'weapon_knife_outdoor' should be mapped to EqKnifeOutdoor")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_stiletto"), "'weapon_knife_stiletto' should be mapped to EqKnifeStiletto")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_widowmaker"), "'weapon_knife_widowmaker' should be mapped to EqKnifeWidowmaker")
assert.Equal(t, EqKnife, MapEquipment("weapon_knife_skeleton"), "'weapon_knife_skeleton' should be mapped to EqKnifeSkeleton")
}

func TestEquipment_Class(t *testing.T) {
assert.Equal(t, EqClassUnknown, NewEquipment(EqUnknown).Class(), "EqUnknown should have the class EqClassUnknown")
assert.Equal(t, EqClassPistols, NewEquipment(EqP2000).Class(), "EqP2000 should have the class EqClassPistols")
Expand Down
16 changes: 15 additions & 1 deletion pkg/demoinfocs/datatables.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import (
st "github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/sendtables"
)

const (
knifePrefix = uint64(500)
)

func (p *parser) mapEquipment() {
if p.isSource2() {
return
Expand Down Expand Up @@ -912,9 +916,17 @@ func (p *parser) nadeProjectileDestroyed(proj *common.GrenadeProjectile) {
}

func (p *parser) bindWeaponS2(entity st.Entity) {
var wepType common.EquipmentType

entityID := entity.ID()
itemIndex := entity.PropertyValueMust("m_iItemDefinitionIndex").S2UInt64()
wepType := common.EquipmentIndexMapping[itemIndex]
rawWeaponType := common.EquipmentIndexMapping[itemIndex]

if itemIndex >= knifePrefix {
wepType = common.EqKnife
} else {
wepType = common.EquipmentIndexMapping[itemIndex]
}

if wepType == common.EqUnknown {
fmt.Println("unknown equipment with index", itemIndex)
Expand All @@ -930,9 +942,11 @@ func (p *parser) bindWeaponS2(entity st.Entity) {
equipment, exists := p.gameState.weapons[entityID]
if !exists {
equipment = common.NewEquipment(wepType)
equipment.RawEquipment = rawWeaponType
p.gameState.weapons[entityID] = equipment
} else {
equipment.Type = wepType
equipment.RawEquipment = rawWeaponType
}

equipment.Entity = entity
Expand Down