Skip to content

Commit 49dacdb

Browse files
committed
Parse PlayerOwners and PlayerSides from map data
1 parent 4d2f1f6 commit 49dacdb

File tree

4 files changed

+126
-2
lines changed

4 files changed

+126
-2
lines changed

cmd/screp/screp.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626

2727
const (
2828
appName = "screp"
29-
appVersion = "v1.7.1"
29+
appVersion = "v1.7.2"
3030
appAuthor = "Andras Belicza"
3131
appHome = "https://github.com/icza/screp"
3232
)

rep/mapdata.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ type MapData struct {
2424
// Scenario description
2525
Description string
2626

27+
// PlayerOwners defines the player types (player owners).
28+
PlayerOwners []*repcore.PlayerOwner
29+
30+
// PlayerSides defines the player sides (player races).
31+
PlayerSides []*repcore.PlayerSide
32+
2733
// Tiles is the tile data of the map (within the tile set): width x height elements.
2834
// 1 Tile is 32 units (pixel)
2935
Tiles []uint16
@@ -41,6 +47,16 @@ type MapData struct {
4147
Debug *MapDataDebug `json:"-"`
4248
}
4349

50+
// MaxHumanPlayers returns the max number of human players on the map.
51+
func (md *MapData) MaxHumanPlayers() (count int) {
52+
for _, owner := range md.PlayerOwners {
53+
if owner == repcore.PlayerOwnerHumanOpenSlot {
54+
count++
55+
}
56+
}
57+
return
58+
}
59+
4460
// Resource describes a resource (mineral field of vespene geyser).
4561
type Resource struct {
4662
// Location of the resource

rep/repcore/enums.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,3 +389,89 @@ func TileSetByID(ID uint16) *TileSet {
389389
}
390390
return &TileSet{UnknownEnum(ID), ID}
391391
}
392+
393+
// PlayerOwner describes a player owner.
394+
type PlayerOwner struct {
395+
Enum
396+
397+
// ID as it appears in replays
398+
ID uint8
399+
}
400+
401+
// PlayerOwners is an enumeration of the possible player owners
402+
var PlayerOwners = []*PlayerOwner{
403+
{Enum{"Inactive"}, 0x00},
404+
{Enum{"Computer (game)"}, 0x01},
405+
{Enum{"Occupied by Human Player"}, 0x02},
406+
{Enum{"Rescue Passive"}, 0x03},
407+
{Enum{"Unused"}, 0x04},
408+
{Enum{"Computer"}, 0x05},
409+
{Enum{"Human (Open Slot)"}, 0x06},
410+
{Enum{"Neutral"}, 0x07},
411+
{Enum{"Closed slot"}, 0x08},
412+
}
413+
414+
// Named player owners
415+
var (
416+
PlayerOwnerInactive = PlayerOwners[0]
417+
PlayerOwnerComputerGame = PlayerOwners[1]
418+
PlayerOwnerOccupiedByHumanPlayer = PlayerOwners[2]
419+
PlayerOwnerRescuePassive = PlayerOwners[3]
420+
PlayerOwnerUnused = PlayerOwners[4]
421+
PlayerOwnerComputer = PlayerOwners[5]
422+
PlayerOwnerHumanOpenSlot = PlayerOwners[6]
423+
PlayerOwnerNeutral = PlayerOwners[7]
424+
PlayerOwnerClosedSlot = PlayerOwners[8]
425+
)
426+
427+
// PlayerOwnerByID returns the PlayerOwner for a given ID.
428+
// A new PlayerOwner with Unknown name is returned if one is not found
429+
// for the given ID (preserving the unknown ID).
430+
func PlayerOwnerByID(ID uint8) *PlayerOwner {
431+
if int(ID) < len(PlayerOwners) {
432+
return PlayerOwners[ID]
433+
}
434+
return &PlayerOwner{UnknownEnum(ID), ID}
435+
}
436+
437+
// PlayerSide describes a player side (race).
438+
type PlayerSide struct {
439+
Enum
440+
441+
// ID as it appears in replays
442+
ID uint8
443+
}
444+
445+
// PlayerSides is an enumeration of the possible player sides
446+
var PlayerSides = []*PlayerSide{
447+
{Enum{"Zerg"}, 0x00},
448+
{Enum{"Terran"}, 0x01},
449+
{Enum{"Protoss"}, 0x02},
450+
{Enum{"Invalid (Independent)"}, 0x03},
451+
{Enum{"Invalid (Neutral)"}, 0x04},
452+
{Enum{"User Selectable"}, 0x05},
453+
{Enum{"Random (Forced)"}, 0x06}, // Acts as a selected race
454+
{Enum{"Inactive"}, 0x07},
455+
}
456+
457+
// Named player sides
458+
var (
459+
PlayerSideZerg = PlayerSides[0]
460+
PlayerSideTerran = PlayerSides[1]
461+
PlayerSideProtoss = PlayerSides[2]
462+
PlayerSideInvalidIndependent = PlayerSides[3]
463+
PlayerSideInvalidNeutral = PlayerSides[4]
464+
PlayerSideUserSelectable = PlayerSides[5]
465+
PlayerSideRandomForced = PlayerSides[6]
466+
PlayerSideInactive = PlayerSides[7]
467+
)
468+
469+
// PlayerSideByID returns the PlayerSide for a given ID.
470+
// A new PlayerSide with Unknown name is returned if one is not found
471+
// for the given ID (preserving the unknown ID).
472+
func PlayerSideByID(ID uint8) *PlayerSide {
473+
if int(ID) < len(PlayerSides) {
474+
return PlayerSides[ID]
475+
}
476+
return &PlayerSide{UnknownEnum(ID), ID}
477+
}

repparser/repparser.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ https://github.com/neivv/jssuh
3131
3232
Map Data format:
3333
34+
https://www.starcraftai.com/wiki/CHK_Format
35+
3436
http://www.staredit.net/wiki/index.php/Scenario.chk
3537
3638
http://blog.naver.com/PostView.nhn?blogId=wisdomswrap&logNo=60119755717&parentCategoryNo=&categoryNo=19&viewDate=&isShowPopularPosts=false&from=postView
@@ -59,7 +61,7 @@ import (
5961

6062
const (
6163
// Version is a Semver2 compatible version of the parser.
62-
Version = "v1.8.1"
64+
Version = "v1.8.2"
6365
)
6466

6567
var (
@@ -735,6 +737,26 @@ func parseMapData(data []byte, r *rep.Replay, cfg Config) error {
735737
r.Header.MapHeight = height
736738
}
737739
}
740+
case "OWNR": // StarCraft Player Types
741+
count := uint32(12) // 12 bytes, 1 for each player
742+
if count > ssSize {
743+
count = ssSize
744+
}
745+
owners := sr.readSlice(count)
746+
md.PlayerOwners = make([]*repcore.PlayerOwner, len(owners))
747+
for i, id := range owners {
748+
md.PlayerOwners[i] = repcore.PlayerOwnerByID(id)
749+
}
750+
case "SIDE": // Player races
751+
count := uint32(12) // 12 bytes, 1 for each player
752+
if count > ssSize {
753+
count = ssSize
754+
}
755+
sides := sr.readSlice(count)
756+
md.PlayerSides = make([]*repcore.PlayerSide, len(sides))
757+
for i, id := range sides {
758+
md.PlayerSides[i] = repcore.PlayerSideByID(id)
759+
}
738760
case "MTXM": // Tile sub-section
739761
// map_width*map_height (a tile is an uint16 value)
740762
maxI := ssSize / 2

0 commit comments

Comments
 (0)