Separate hats, face hair, glasses from hair (fixes #601)
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "head", "body", "hair"],
|
||||
["gun_r", "gun_l", "legs", "head", "body", "hair"],
|
||||
["gun_l", "legs", "body", "head", "hair", "gun_r"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "hair", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "head", "body", "hair"]
|
||||
["gun_r", "gun_l", "legs", "head", "body"],
|
||||
["gun_r", "gun_l", "legs", "head", "body"],
|
||||
["gun_l", "legs", "body", "head", "gun_r"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "head", "body"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 10]],
|
||||
"idle": [[0, 10]],
|
||||
"run": [
|
||||
[0, 11], [0, 10], [0, 9], [0, 10], [0, 11], [0, 10], [0, 9], [0, 10]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 10]],
|
||||
"idle": [[0, 10]],
|
||||
@@ -41,9 +34,6 @@
|
||||
}
|
||||
},
|
||||
"Dir": {
|
||||
"Hair": [
|
||||
[0, -2], [2, -1], [4, 0], [2, 1], [0, 2], [-2, 1], [-4, 0], [-2, -1]
|
||||
],
|
||||
"Head": [
|
||||
[0, -2], [2, -1], [4, 0], [2, 1], [0, 2], [-2, 1], [-4, 0], [-2, -1]
|
||||
],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
"run": [
|
||||
[0, 14], [0, 14], [0, 13], [0, 13], [0, 12], [0, 12], [0, 13], [0, 13]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 16]],
|
||||
"idle": [[0, 16]],
|
||||
"run": [
|
||||
[0, 17], [0, 16], [0, 15], [0, 16], [0, 17], [0, 16], [0, 15], [0, 16]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 16]],
|
||||
"idle": [[0, 16]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
"run": [
|
||||
[0, 13], [0, 13], [0, 13], [0, 13], [0, 13], [0, 13], [0, 13], [0, 13]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "head", "body", "hair"],
|
||||
["gun_r", "gun_l", "legs", "head", "body", "hair"],
|
||||
["gun_l", "legs", "body", "head", "hair", "gun_r"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "hair", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "head", "body", "hair"]
|
||||
["gun_r", "gun_l", "legs", "head", "body"],
|
||||
["gun_r", "gun_l", "legs", "head", "body"],
|
||||
["gun_l", "legs", "body", "head", "gun_r"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "head", "body"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 10]],
|
||||
"idle": [[0, 10]],
|
||||
"run": [
|
||||
[0, 11], [0, 10], [0, 9], [0, 10], [0, 11], [0, 10], [0, 9], [0, 10]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 10]],
|
||||
"idle": [[0, 10]],
|
||||
@@ -41,9 +34,6 @@
|
||||
}
|
||||
},
|
||||
"Dir": {
|
||||
"Hair": [
|
||||
[0, -2], [2, -1], [4, 0], [2, 1], [0, 2], [-2, 1], [-4, 0], [-2, -1]
|
||||
],
|
||||
"Head": [
|
||||
[0, -2], [2, -1], [4, 0], [2, 1], [0, 2], [-2, 1], [-4, 0], [-2, -1]
|
||||
],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
"run": [
|
||||
[0, 14], [0, 14], [0, 13], [0, 13], [0, 12], [0, 12], [0, 13], [0, 13]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 16]],
|
||||
"idle": [[0, 16]],
|
||||
"run": [
|
||||
[0, 17], [0, 16], [0, 15], [0, 16], [0, 17], [0, 16], [0, 15], [0, 16]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 16]],
|
||||
"idle": [[0, 16]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
"run": [
|
||||
[0, 13], [0, 13], [0, 13], [0, 13], [0, 13], [0, 13], [0, 13], [0, 13]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "head", "body", "hair"],
|
||||
["gun_r", "gun_l", "legs", "head", "body", "hair"],
|
||||
["gun_l", "legs", "body", "head", "hair", "gun_r"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "hair", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "head", "body", "hair"]
|
||||
["gun_r", "gun_l", "legs", "head", "body"],
|
||||
["gun_r", "gun_l", "legs", "head", "body"],
|
||||
["gun_l", "legs", "body", "head", "gun_r"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "head", "body"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 10]],
|
||||
"idle": [[0, 10]],
|
||||
"run": [
|
||||
[0, 11], [0, 10], [0, 9], [0, 10], [0, 11], [0, 10], [0, 9], [0, 10]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 10]],
|
||||
"idle": [[0, 10]],
|
||||
@@ -41,9 +34,6 @@
|
||||
}
|
||||
},
|
||||
"Dir": {
|
||||
"Hair": [
|
||||
[0, -2], [2, -1], [4, 0], [2, 1], [0, 2], [-2, 1], [-4, 0], [-2, -1]
|
||||
],
|
||||
"Head": [
|
||||
[0, -2], [2, -1], [4, 0], [2, 1], [0, 2], [-2, 1], [-4, 0], [-2, -1]
|
||||
],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 16]],
|
||||
"idle": [[0, 16]],
|
||||
"run": [
|
||||
[0, 17], [0, 16], [0, 15], [0, 16], [0, 17], [0, 16], [0, 15], [0, 16]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 16]],
|
||||
"idle": [[0, 16]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
"run": [
|
||||
[0, 14], [0, 13], [0, 12], [0, 13], [0, 14], [0, 13], [0, 12], [0, 13]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
"run": [
|
||||
[0, 13], [0, 13], [0, 13], [0, 13], [0, 13], [0, 13], [0, 13], [0, 13]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
|
@@ -35,7 +35,9 @@
|
||||
},
|
||||
"Sounds": "alien",
|
||||
"BloodColor": "00ff00",
|
||||
"HasHair": false
|
||||
"HasHair": false,
|
||||
"HasFacehair": false,
|
||||
"HasGlasses": false
|
||||
},
|
||||
{
|
||||
"Name": "Mad bug-eye",
|
||||
@@ -45,7 +47,9 @@
|
||||
},
|
||||
"Sounds": "alien",
|
||||
"BloodColor": "00ff00",
|
||||
"HasHair": false
|
||||
"HasHair": false,
|
||||
"HasFacehair": false,
|
||||
"HasGlasses": false
|
||||
},
|
||||
{
|
||||
"Name": "Robot",
|
||||
@@ -55,7 +59,9 @@
|
||||
},
|
||||
"Sounds": "alien",
|
||||
"BloodColor": "0000ff",
|
||||
"HasHair": false
|
||||
"HasHair": false,
|
||||
"HasFacehair": false,
|
||||
"HasGlasses": false
|
||||
},
|
||||
{
|
||||
"Name": "Lady",
|
||||
@@ -83,7 +89,9 @@
|
||||
"Body": "skinny",
|
||||
"Sounds": "zombie",
|
||||
"Footsteps": "bones",
|
||||
"BloodColor": "ffffff"
|
||||
"BloodColor": "ffffff",
|
||||
"HasHair": false,
|
||||
"HasFacehair": false
|
||||
},
|
||||
{
|
||||
"Name": "Big Bones",
|
||||
@@ -93,8 +101,12 @@
|
||||
},
|
||||
"Body": "big_skinny",
|
||||
"Sounds": "zombie",
|
||||
"Footsteps": "bones",
|
||||
"BloodColor": "ffffff",
|
||||
"HasHair": false
|
||||
"HasHair": false,
|
||||
"HasFacehair": false,
|
||||
"HasHat": false,
|
||||
"HasGlasses": false
|
||||
},
|
||||
{
|
||||
"Name": "Dog",
|
||||
@@ -102,7 +114,11 @@
|
||||
"Type": "Directional",
|
||||
"Sprites": "chars/heads/dog"
|
||||
},
|
||||
"Sounds": "dog"
|
||||
"Sounds": "dog",
|
||||
"HasHair": false,
|
||||
"HasFacehair": false,
|
||||
"HasHat": false,
|
||||
"HasGlasses": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_l", "legs", "body", "head", "hair", "gun_r"],
|
||||
["gun_l", "legs", "body", "head", "hair", "gun_r"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "hair", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_l", "legs", "body", "head", "gun_r"],
|
||||
["gun_l", "legs", "body", "head", "gun_r"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
"run": [
|
||||
[0, 14], [0, 13], [0, 12], [0, 13], [0, 14], [0, 13], [0, 12], [0, 13]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_l", "legs", "body", "head", "hair", "gun_r"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "hair", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_l", "legs", "body", "head", "gun_r"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 16]],
|
||||
"idle": [[0, 16]],
|
||||
"run": [
|
||||
[0, 17], [0, 16], [0, 15], [0, 16], [0, 17], [0, 16], [0, 15], [0, 16]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 16]],
|
||||
"idle": [[0, 16]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_l", "legs", "body", "head", "hair", "gun_r"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "hair", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_l", "legs", "body", "head", "gun_r"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 14]],
|
||||
"idle": [[0, 14]],
|
||||
"run": [
|
||||
[0, 15], [0, 14], [0, 13], [0, 14], [0, 15], [0, 14], [0, 13], [0, 14]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 14]],
|
||||
"idle": [[0, 14]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_l", "legs", "body", "head", "hair", "gun_r"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "hair", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_l", "legs", "body", "head", "gun_r"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 16]],
|
||||
"idle": [[0, 16]],
|
||||
"run": [
|
||||
[0, 17], [0, 16], [0, 15], [0, 16], [0, 17], [0, 16], [0, 15], [0, 16]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 16]],
|
||||
"idle": [[0, 16]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "gun_l", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 8]],
|
||||
"idle": [[0, 8]],
|
||||
"run": [
|
||||
[0, 8], [0, 7], [0, 7], [0, 8], [0, 8], [0, 9], [0, 9], [0, 8]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 8]],
|
||||
"idle": [[0, 8]],
|
||||
@@ -41,9 +34,6 @@
|
||||
}
|
||||
},
|
||||
"Dir": {
|
||||
"Hair": [
|
||||
[0, -3], [4, -3], [6, 0], [6, 4], [0, 6], [-6, 4], [-7, 0], [-5, -3]
|
||||
],
|
||||
"Head": [
|
||||
[0, -3], [4, -3], [6, 0], [6, 4], [0, 6], [-6, 4], [-7, 0], [-5, -3]
|
||||
],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_l", "legs", "body", "head", "hair", "gun_r"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "hair", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_l", "legs", "body", "head", "gun_r"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 16]],
|
||||
"idle": [[0, 16]],
|
||||
"run": [
|
||||
[0, 17], [0, 16], [0, 15], [0, 16], [0, 17], [0, 16], [0, 15], [0, 16]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 16]],
|
||||
"idle": [[0, 16]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_l", "legs", "body", "head", "hair", "gun_r"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "hair", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_l", "legs", "body", "head", "gun_r"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
"run": [
|
||||
[0, 13], [0, 13], [0, 13], [0, 13], [0, 13], [0, 13], [0, 13], [0, 13]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_l", "legs", "body", "head", "hair", "gun_r"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "hair", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_l", "legs", "body", "head", "gun_r"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
"run": [
|
||||
[0, 14], [0, 13], [0, 12], [0, 13], [0, 14], [0, 13], [0, 12], [0, 13]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_l", "legs", "body", "head", "hair", "gun_r"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "hair", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_l", "legs", "body", "head", "gun_r"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
"run": [
|
||||
[0, 14], [0, 13], [0, 12], [0, 13], [0, 14], [0, 13], [0, 12], [0, 13]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 13]],
|
||||
"idle": [[0, 13]],
|
||||
|
BIN
graphics/chars/facehairs/beard_10x10.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
graphics/chars/facehairs/dutch_10x10.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
graphics/chars/facehairs/handlebar_10x10.png
Normal file
After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 9.7 KiB |
Before Width: | Height: | Size: 8.4 KiB |
BIN
graphics/chars/hairs/rattail_10x10.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
graphics/chars/hairs/widows_10x10.png
Normal file
After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
@@ -1,23 +1,23 @@
|
||||
The following are original C-Dogs/Cyberdogs heads, by Ronny Wester CC-BY 3.0 (see graphics/originals.txt)
|
||||
- beard
|
||||
The following are extracted from original C-Dogs/Cyberdogs heads, by Ronny Wester CC-BY 3.0 (see graphics/originals.txt)
|
||||
- beret
|
||||
- cyber_shades
|
||||
- cyborg
|
||||
- dutch
|
||||
- eye_patch
|
||||
- flattop
|
||||
- goggles
|
||||
- hogan
|
||||
- mohawk
|
||||
- ponytail
|
||||
- professor
|
||||
- riot_helmet
|
||||
- shades
|
||||
- ski_goggles
|
||||
|
||||
The following are derived from original C-Dogs/cyberdogs heads. Please still attribute to Ronny Wester using CC-BY 3.0
|
||||
The following are derived from original C-Dogs/Cyberdogs heads. Please still attribute to Ronny Wester using CC-BY 3.0
|
||||
- beard
|
||||
- donut
|
||||
- mad_doc
|
||||
- dutch
|
||||
- handlebar
|
||||
- rattail
|
||||
- widows
|
||||
|
||||
The following are original and licensed as CC0
|
||||
|
@@ -7,10 +7,10 @@
|
||||
"SkipWeaponMenu": false,
|
||||
"BuyAndSell": true,
|
||||
"RandomPickups": false,
|
||||
"DoorOpenTicks": 0,
|
||||
"DoorOpenTicks": 70,
|
||||
"Lives": 0,
|
||||
"MaxLives": 4,
|
||||
"PlayerHP": 20,
|
||||
"PlayerMaxHP": 50,
|
||||
"Missions": 1
|
||||
"Missions": 5
|
||||
}
|
@@ -1,23 +1,6 @@
|
||||
{
|
||||
"Version": 13,
|
||||
"Version": 14,
|
||||
"Characters": [{
|
||||
"Class": "Ogre",
|
||||
"Skin": "00ff00ff",
|
||||
"Arms": "404040ff",
|
||||
"Body": "404040ff",
|
||||
"Legs": "404040ff",
|
||||
"Hair": "000000ff",
|
||||
"Feet": "404040ff",
|
||||
"speed": 256,
|
||||
"Gun": "DumbGun",
|
||||
"maxHealth": 40,
|
||||
"flags": 1024,
|
||||
"probabilityToMove": 50,
|
||||
"probabilityToTrack": 25,
|
||||
"probabilityToShoot": 0,
|
||||
"actionDelay": 15
|
||||
},
|
||||
{
|
||||
"Class": "Jones",
|
||||
"PlayerTemplateName": "Jones",
|
||||
"Skin": "f0944bff",
|
||||
@@ -26,6 +9,9 @@
|
||||
"Legs": "5050a0ff",
|
||||
"Hair": "000000ff",
|
||||
"Feet": "5050a0ff",
|
||||
"Facehair": "000000ff",
|
||||
"Hat": "000000ff",
|
||||
"Glasses": "000000ff",
|
||||
"speed": 256,
|
||||
"Gun": "Machine gun",
|
||||
"maxHealth": 40,
|
||||
@@ -38,13 +24,16 @@
|
||||
{
|
||||
"Class": "Jones",
|
||||
"PlayerTemplateName": "Ice",
|
||||
"HairType": "shades",
|
||||
"GlassesType": "shades",
|
||||
"Skin": "f0944bff",
|
||||
"Arms": "5050a0ff",
|
||||
"Body": "5050a0ff",
|
||||
"Legs": "5050a0ff",
|
||||
"Hair": "000000ff",
|
||||
"Feet": "5050a0ff",
|
||||
"Facehair": "000000ff",
|
||||
"Hat": "000000ff",
|
||||
"Glasses": "000000ff",
|
||||
"speed": 256,
|
||||
"Gun": "Machine gun",
|
||||
"maxHealth": 40,
|
||||
@@ -57,13 +46,16 @@
|
||||
{
|
||||
"Class": "Jones",
|
||||
"PlayerTemplateName": "WarBaby",
|
||||
"HairType": "beret",
|
||||
"HatType": "beret",
|
||||
"Skin": "f0944bff",
|
||||
"Arms": "5050a0ff",
|
||||
"Body": "5050a0ff",
|
||||
"Legs": "5050a0ff",
|
||||
"Hair": "f30202ff",
|
||||
"Feet": "5050a0ff",
|
||||
"Facehair": "f30202ff",
|
||||
"Hat": "f30202ff",
|
||||
"Glasses": "f30202ff",
|
||||
"speed": 256,
|
||||
"Gun": "Machine gun",
|
||||
"maxHealth": 40,
|
||||
@@ -72,5 +64,134 @@
|
||||
"probabilityToTrack": 25,
|
||||
"probabilityToShoot": 2,
|
||||
"actionDelay": 15
|
||||
},
|
||||
{
|
||||
"Class": "Cyborg",
|
||||
"HairType": "flattop",
|
||||
"GlassesType": "cyber_shades",
|
||||
"Skin": "fc8a20ff",
|
||||
"Arms": "9c4f4fff",
|
||||
"Body": "b45f5aff",
|
||||
"Legs": "cb5c5cff",
|
||||
"Hair": "0b0101ff",
|
||||
"Feet": "cd5e5eff",
|
||||
"Facehair": "ff1616ff",
|
||||
"Hat": "ff1616ff",
|
||||
"Glasses": "ff1616ff",
|
||||
"speed": 256,
|
||||
"Gun": "DumbGun",
|
||||
"maxHealth": 40,
|
||||
"flags": 1024,
|
||||
"probabilityToMove": 50,
|
||||
"probabilityToTrack": 25,
|
||||
"probabilityToShoot": 2,
|
||||
"actionDelay": 15
|
||||
},
|
||||
{
|
||||
"Class": "Cyborg",
|
||||
"GlassesType": "cyber_shades",
|
||||
"Skin": "fc8a20ff",
|
||||
"Arms": "f70606ff",
|
||||
"Body": "e9271cff",
|
||||
"Legs": "ec1010ff",
|
||||
"Hair": "0b0101ff",
|
||||
"Feet": "ee0c0cff",
|
||||
"Facehair": "ff1616ff",
|
||||
"Hat": "ff1616ff",
|
||||
"Glasses": "ff1616ff",
|
||||
"speed": 256,
|
||||
"Gun": "Lazer",
|
||||
"maxHealth": 40,
|
||||
"flags": 1024,
|
||||
"probabilityToMove": 50,
|
||||
"probabilityToTrack": 25,
|
||||
"probabilityToShoot": 2,
|
||||
"actionDelay": 15
|
||||
},
|
||||
{
|
||||
"Class": "Cyborg",
|
||||
"GlassesType": "ski_goggles",
|
||||
"Skin": "fc8a20ff",
|
||||
"Arms": "a6a4a4ff",
|
||||
"Body": "a1a0a0ff",
|
||||
"Legs": "a6a6a6ff",
|
||||
"Hair": "0b0101ff",
|
||||
"Feet": "dbd9d9ff",
|
||||
"Facehair": "ff1616ff",
|
||||
"Hat": "ff1616ff",
|
||||
"Glasses": "020000ff",
|
||||
"speed": 256,
|
||||
"Gun": "Gun",
|
||||
"maxHealth": 40,
|
||||
"flags": 1024,
|
||||
"probabilityToMove": 50,
|
||||
"probabilityToTrack": 25,
|
||||
"probabilityToShoot": 2,
|
||||
"actionDelay": 15
|
||||
},
|
||||
{
|
||||
"Class": "Cyborg",
|
||||
"GlassesType": "cyber_shades",
|
||||
"Skin": "fc8a20ff",
|
||||
"Arms": "3a3a3aff",
|
||||
"Body": "3f3f3fff",
|
||||
"Legs": "464646ff",
|
||||
"Hair": "0b0101ff",
|
||||
"Feet": "434343ff",
|
||||
"Facehair": "ff1616ff",
|
||||
"Hat": "ff1616ff",
|
||||
"Glasses": "ff1616ff",
|
||||
"speed": 256,
|
||||
"Gun": "Lazer",
|
||||
"maxHealth": 40,
|
||||
"flags": 1024,
|
||||
"probabilityToMove": 50,
|
||||
"probabilityToTrack": 25,
|
||||
"probabilityToShoot": 2,
|
||||
"actionDelay": 15
|
||||
},
|
||||
{
|
||||
"Class": "Cyborg",
|
||||
"HairType": "donut",
|
||||
"GlassesType": "goggles",
|
||||
"Skin": "fc8a20ff",
|
||||
"Arms": "9c4f4fff",
|
||||
"Body": "b45f5aff",
|
||||
"Legs": "cb5c5cff",
|
||||
"Hair": "0b0101ff",
|
||||
"Feet": "cd5e5eff",
|
||||
"Facehair": "ff1616ff",
|
||||
"Hat": "ff1616ff",
|
||||
"Glasses": "fcfcfcff",
|
||||
"speed": 256,
|
||||
"Gun": "DumbGun",
|
||||
"maxHealth": 40,
|
||||
"flags": 1024,
|
||||
"probabilityToMove": 50,
|
||||
"probabilityToTrack": 25,
|
||||
"probabilityToShoot": 2,
|
||||
"actionDelay": 15
|
||||
},
|
||||
{
|
||||
"Class": "Cyborg",
|
||||
"HatType": "beret",
|
||||
"GlassesType": "cyber_shades",
|
||||
"Skin": "fc8a20ff",
|
||||
"Arms": "4a4a4aff",
|
||||
"Body": "565555ff",
|
||||
"Legs": "5d5d5dff",
|
||||
"Hair": "0b0101ff",
|
||||
"Feet": "545454ff",
|
||||
"Facehair": "ff1616ff",
|
||||
"Hat": "7b7b7bff",
|
||||
"Glasses": "ff1616ff",
|
||||
"speed": 256,
|
||||
"Gun": "TurboLazer",
|
||||
"maxHealth": 40,
|
||||
"flags": 1024,
|
||||
"probabilityToMove": 50,
|
||||
"probabilityToTrack": 25,
|
||||
"probabilityToShoot": 2,
|
||||
"actionDelay": 15
|
||||
}]
|
||||
}
|
@@ -15,8 +15,8 @@
|
||||
"pci_card",
|
||||
"paper",
|
||||
"teddy"],
|
||||
"Count": 8,
|
||||
"Required": 0,
|
||||
"Count": 12,
|
||||
"Required": 6,
|
||||
"Flags": 0
|
||||
}],
|
||||
"Enemies": [0],
|
||||
@@ -84,8 +84,540 @@
|
||||
"Room": {
|
||||
"Name": "tile",
|
||||
"Type": "Floor",
|
||||
"Style": "recessed",
|
||||
"Mask": "707070ff",
|
||||
"Style": "wood",
|
||||
"Mask": "303030ff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": true,
|
||||
"IsOpaque": false,
|
||||
"Shootable": false,
|
||||
"IsRoom": true,
|
||||
"DamageBullet": ""
|
||||
},
|
||||
"Door": {
|
||||
"Name": "door",
|
||||
"Type": "Door",
|
||||
"Style": "office",
|
||||
"Mask": "ffffffff",
|
||||
"MaskAlt": "ffffffff",
|
||||
"CanWalk": false,
|
||||
"IsOpaque": true,
|
||||
"Shootable": true,
|
||||
"IsRoom": true,
|
||||
"DamageBullet": ""
|
||||
}
|
||||
},
|
||||
"Walls": 140,
|
||||
"WallLength": 20,
|
||||
"CorridorWidth": 2,
|
||||
"Rooms": {
|
||||
"Count": 30,
|
||||
"Min": 7,
|
||||
"Max": 10,
|
||||
"Edge": false,
|
||||
"Overlap": false,
|
||||
"Walls": 0,
|
||||
"WallLength": 1,
|
||||
"WallPad": 1
|
||||
},
|
||||
"Squares": 1,
|
||||
"ExitEnabled": true,
|
||||
"Doors": {
|
||||
"Enabled": false,
|
||||
"Min": 2,
|
||||
"Max": 2,
|
||||
"RandomPos": false
|
||||
},
|
||||
"Pillars": {
|
||||
"Count": 0,
|
||||
"Min": 2,
|
||||
"Max": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"Title": "Mission 2",
|
||||
"Description": "",
|
||||
"Type": "Classic",
|
||||
"Width": 100,
|
||||
"Height": 100,
|
||||
"ExitStyle": "hazard",
|
||||
"KeyStyle": "office",
|
||||
"Objectives": [{
|
||||
"Description": "",
|
||||
"Type": "Collect",
|
||||
"Pickups": ["folder",
|
||||
"disk1",
|
||||
"pci_card",
|
||||
"paper",
|
||||
"teddy"],
|
||||
"Count": 16,
|
||||
"Required": 8,
|
||||
"Flags": 0
|
||||
}],
|
||||
"Enemies": [0],
|
||||
"SpecialChars": [],
|
||||
"MapObjectDensities": [{
|
||||
"MapObject": "crate",
|
||||
"Density": 45
|
||||
},
|
||||
{
|
||||
"MapObject": "box",
|
||||
"Density": 45
|
||||
},
|
||||
{
|
||||
"MapObject": "fan",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "barrel_blue",
|
||||
"Density": 30
|
||||
},
|
||||
{
|
||||
"MapObject": "box3_gray",
|
||||
"Density": 30
|
||||
}],
|
||||
"EnemyDensity": 13,
|
||||
"Weapons": ["Barehanded",
|
||||
"Chainsaw",
|
||||
"2xChainsaw",
|
||||
"3xChainsaw",
|
||||
"4xChainsaw",
|
||||
"5xChainsaw",
|
||||
"MiniGun",
|
||||
"Launcher",
|
||||
"Flamer",
|
||||
"Powergun",
|
||||
"Blaster",
|
||||
"MegaGun"],
|
||||
"WeaponPersist": false,
|
||||
"SkipDebrief": false,
|
||||
"TileClasses": {
|
||||
"Wall": {
|
||||
"Name": "wall",
|
||||
"Type": "Wall",
|
||||
"Style": "brick",
|
||||
"Mask": "34345cff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": false,
|
||||
"IsOpaque": true,
|
||||
"Shootable": true,
|
||||
"IsRoom": false,
|
||||
"DamageBullet": ""
|
||||
},
|
||||
"Floor": {
|
||||
"Name": "tile",
|
||||
"Type": "Floor",
|
||||
"Style": "smallsquare2",
|
||||
"Mask": "282848ff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": true,
|
||||
"IsOpaque": false,
|
||||
"Shootable": false,
|
||||
"IsRoom": false,
|
||||
"DamageBullet": ""
|
||||
},
|
||||
"Room": {
|
||||
"Name": "tile",
|
||||
"Type": "Floor",
|
||||
"Style": "smallsquare2",
|
||||
"Mask": "282848ff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": true,
|
||||
"IsOpaque": false,
|
||||
"Shootable": false,
|
||||
"IsRoom": true,
|
||||
"DamageBullet": ""
|
||||
},
|
||||
"Door": {
|
||||
"Name": "door",
|
||||
"Type": "Door",
|
||||
"Style": "office",
|
||||
"Mask": "ffffffff",
|
||||
"MaskAlt": "ffffffff",
|
||||
"CanWalk": false,
|
||||
"IsOpaque": true,
|
||||
"Shootable": true,
|
||||
"IsRoom": true,
|
||||
"DamageBullet": ""
|
||||
}
|
||||
},
|
||||
"Walls": 140,
|
||||
"WallLength": 20,
|
||||
"CorridorWidth": 2,
|
||||
"Rooms": {
|
||||
"Count": 30,
|
||||
"Min": 7,
|
||||
"Max": 10,
|
||||
"Edge": false,
|
||||
"Overlap": false,
|
||||
"Walls": 0,
|
||||
"WallLength": 1,
|
||||
"WallPad": 1
|
||||
},
|
||||
"Squares": 1,
|
||||
"ExitEnabled": true,
|
||||
"Doors": {
|
||||
"Enabled": false,
|
||||
"Min": 2,
|
||||
"Max": 2,
|
||||
"RandomPos": false
|
||||
},
|
||||
"Pillars": {
|
||||
"Count": 0,
|
||||
"Min": 2,
|
||||
"Max": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"Title": "Mission 3",
|
||||
"Description": "",
|
||||
"Type": "Classic",
|
||||
"Width": 100,
|
||||
"Height": 100,
|
||||
"ExitStyle": "hazard",
|
||||
"KeyStyle": "office",
|
||||
"Objectives": [{
|
||||
"Description": "",
|
||||
"Type": "Collect",
|
||||
"Pickups": ["folder",
|
||||
"disk1",
|
||||
"pci_card",
|
||||
"paper",
|
||||
"teddy"],
|
||||
"Count": 20,
|
||||
"Required": 10,
|
||||
"Flags": 0
|
||||
}],
|
||||
"Enemies": [0],
|
||||
"SpecialChars": [],
|
||||
"MapObjectDensities": [{
|
||||
"MapObject": "crate",
|
||||
"Density": 45
|
||||
},
|
||||
{
|
||||
"MapObject": "box",
|
||||
"Density": 45
|
||||
},
|
||||
{
|
||||
"MapObject": "fan",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "barrel_blue",
|
||||
"Density": 30
|
||||
},
|
||||
{
|
||||
"MapObject": "box3_gray",
|
||||
"Density": 30
|
||||
}],
|
||||
"EnemyDensity": 13,
|
||||
"Weapons": ["Barehanded",
|
||||
"Chainsaw",
|
||||
"2xChainsaw",
|
||||
"3xChainsaw",
|
||||
"4xChainsaw",
|
||||
"5xChainsaw",
|
||||
"MiniGun",
|
||||
"Launcher",
|
||||
"Flamer",
|
||||
"Powergun",
|
||||
"Blaster",
|
||||
"MegaGun"],
|
||||
"WeaponPersist": false,
|
||||
"SkipDebrief": false,
|
||||
"TileClasses": {
|
||||
"Wall": {
|
||||
"Name": "wall",
|
||||
"Type": "Wall",
|
||||
"Style": "brick",
|
||||
"Mask": "303030ff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": false,
|
||||
"IsOpaque": true,
|
||||
"Shootable": true,
|
||||
"IsRoom": false,
|
||||
"DamageBullet": ""
|
||||
},
|
||||
"Floor": {
|
||||
"Name": "tile",
|
||||
"Type": "Floor",
|
||||
"Style": "dirt",
|
||||
"Mask": "584418ff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": true,
|
||||
"IsOpaque": false,
|
||||
"Shootable": false,
|
||||
"IsRoom": false,
|
||||
"DamageBullet": ""
|
||||
},
|
||||
"Room": {
|
||||
"Name": "tile",
|
||||
"Type": "Floor",
|
||||
"Style": "dirt",
|
||||
"Mask": "584418ff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": true,
|
||||
"IsOpaque": false,
|
||||
"Shootable": false,
|
||||
"IsRoom": true,
|
||||
"DamageBullet": ""
|
||||
},
|
||||
"Door": {
|
||||
"Name": "door",
|
||||
"Type": "Door",
|
||||
"Style": "office",
|
||||
"Mask": "ffffffff",
|
||||
"MaskAlt": "ffffffff",
|
||||
"CanWalk": false,
|
||||
"IsOpaque": true,
|
||||
"Shootable": true,
|
||||
"IsRoom": true,
|
||||
"DamageBullet": ""
|
||||
}
|
||||
},
|
||||
"Walls": 140,
|
||||
"WallLength": 20,
|
||||
"CorridorWidth": 2,
|
||||
"Rooms": {
|
||||
"Count": 30,
|
||||
"Min": 7,
|
||||
"Max": 10,
|
||||
"Edge": false,
|
||||
"Overlap": false,
|
||||
"Walls": 0,
|
||||
"WallLength": 1,
|
||||
"WallPad": 1
|
||||
},
|
||||
"Squares": 1,
|
||||
"ExitEnabled": true,
|
||||
"Doors": {
|
||||
"Enabled": false,
|
||||
"Min": 2,
|
||||
"Max": 2,
|
||||
"RandomPos": false
|
||||
},
|
||||
"Pillars": {
|
||||
"Count": 0,
|
||||
"Min": 2,
|
||||
"Max": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"Title": "Mission 4",
|
||||
"Description": "",
|
||||
"Type": "Classic",
|
||||
"Width": 100,
|
||||
"Height": 100,
|
||||
"ExitStyle": "hazard",
|
||||
"KeyStyle": "office",
|
||||
"Objectives": [{
|
||||
"Description": "",
|
||||
"Type": "Collect",
|
||||
"Pickups": ["folder",
|
||||
"disk1",
|
||||
"pci_card",
|
||||
"paper",
|
||||
"teddy"],
|
||||
"Count": 24,
|
||||
"Required": 12,
|
||||
"Flags": 0
|
||||
}],
|
||||
"Enemies": [0],
|
||||
"SpecialChars": [],
|
||||
"MapObjectDensities": [{
|
||||
"MapObject": "crate",
|
||||
"Density": 45
|
||||
},
|
||||
{
|
||||
"MapObject": "box",
|
||||
"Density": 45
|
||||
},
|
||||
{
|
||||
"MapObject": "fan",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "barrel_blue",
|
||||
"Density": 30
|
||||
},
|
||||
{
|
||||
"MapObject": "box3_gray",
|
||||
"Density": 30
|
||||
}],
|
||||
"EnemyDensity": 13,
|
||||
"Weapons": ["Barehanded",
|
||||
"Chainsaw",
|
||||
"2xChainsaw",
|
||||
"3xChainsaw",
|
||||
"4xChainsaw",
|
||||
"5xChainsaw",
|
||||
"MiniGun",
|
||||
"Launcher",
|
||||
"Flamer",
|
||||
"Powergun",
|
||||
"Blaster",
|
||||
"MegaGun"],
|
||||
"WeaponPersist": false,
|
||||
"SkipDebrief": false,
|
||||
"TileClasses": {
|
||||
"Wall": {
|
||||
"Name": "wall",
|
||||
"Type": "Wall",
|
||||
"Style": "brick",
|
||||
"Mask": "303030ff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": false,
|
||||
"IsOpaque": true,
|
||||
"Shootable": true,
|
||||
"IsRoom": false,
|
||||
"DamageBullet": ""
|
||||
},
|
||||
"Floor": {
|
||||
"Name": "tile",
|
||||
"Type": "Floor",
|
||||
"Style": "wood",
|
||||
"Mask": "303030ff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": true,
|
||||
"IsOpaque": false,
|
||||
"Shootable": false,
|
||||
"IsRoom": false,
|
||||
"DamageBullet": ""
|
||||
},
|
||||
"Room": {
|
||||
"Name": "tile",
|
||||
"Type": "Floor",
|
||||
"Style": "wood",
|
||||
"Mask": "303030ff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": true,
|
||||
"IsOpaque": false,
|
||||
"Shootable": false,
|
||||
"IsRoom": true,
|
||||
"DamageBullet": ""
|
||||
},
|
||||
"Door": {
|
||||
"Name": "door",
|
||||
"Type": "Door",
|
||||
"Style": "office",
|
||||
"Mask": "ffffffff",
|
||||
"MaskAlt": "ffffffff",
|
||||
"CanWalk": false,
|
||||
"IsOpaque": true,
|
||||
"Shootable": true,
|
||||
"IsRoom": true,
|
||||
"DamageBullet": ""
|
||||
}
|
||||
},
|
||||
"Walls": 140,
|
||||
"WallLength": 20,
|
||||
"CorridorWidth": 2,
|
||||
"Rooms": {
|
||||
"Count": 30,
|
||||
"Min": 7,
|
||||
"Max": 10,
|
||||
"Edge": false,
|
||||
"Overlap": false,
|
||||
"Walls": 0,
|
||||
"WallLength": 1,
|
||||
"WallPad": 1
|
||||
},
|
||||
"Squares": 1,
|
||||
"ExitEnabled": true,
|
||||
"Doors": {
|
||||
"Enabled": false,
|
||||
"Min": 2,
|
||||
"Max": 2,
|
||||
"RandomPos": false
|
||||
},
|
||||
"Pillars": {
|
||||
"Count": 0,
|
||||
"Min": 2,
|
||||
"Max": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"Title": "Mission 5",
|
||||
"Description": "",
|
||||
"Type": "Classic",
|
||||
"Width": 100,
|
||||
"Height": 100,
|
||||
"ExitStyle": "hazard",
|
||||
"KeyStyle": "office",
|
||||
"Objectives": [{
|
||||
"Description": "",
|
||||
"Type": "Kill",
|
||||
"Index": 0,
|
||||
"Count": 90,
|
||||
"Required": 70,
|
||||
"Flags": 0
|
||||
}],
|
||||
"Enemies": [0],
|
||||
"SpecialChars": [],
|
||||
"MapObjectDensities": [{
|
||||
"MapObject": "crate",
|
||||
"Density": 45
|
||||
},
|
||||
{
|
||||
"MapObject": "box",
|
||||
"Density": 45
|
||||
},
|
||||
{
|
||||
"MapObject": "fan",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "barrel_blue",
|
||||
"Density": 30
|
||||
},
|
||||
{
|
||||
"MapObject": "box3_gray",
|
||||
"Density": 30
|
||||
}],
|
||||
"EnemyDensity": 13,
|
||||
"Weapons": ["Barehanded",
|
||||
"Chainsaw",
|
||||
"2xChainsaw",
|
||||
"3xChainsaw",
|
||||
"4xChainsaw",
|
||||
"5xChainsaw",
|
||||
"MiniGun",
|
||||
"Launcher",
|
||||
"Flamer",
|
||||
"Powergun",
|
||||
"Blaster",
|
||||
"MegaGun"],
|
||||
"WeaponPersist": true,
|
||||
"SkipDebrief": false,
|
||||
"TileClasses": {
|
||||
"Wall": {
|
||||
"Name": "wall",
|
||||
"Type": "Wall",
|
||||
"Style": "brick",
|
||||
"Mask": "303030ff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": false,
|
||||
"IsOpaque": true,
|
||||
"Shootable": true,
|
||||
"IsRoom": false,
|
||||
"DamageBullet": ""
|
||||
},
|
||||
"Floor": {
|
||||
"Name": "tile",
|
||||
"Type": "Floor",
|
||||
"Style": "dirt",
|
||||
"Mask": "584418ff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": true,
|
||||
"IsOpaque": false,
|
||||
"Shootable": false,
|
||||
"IsRoom": false,
|
||||
"DamageBullet": ""
|
||||
},
|
||||
"Room": {
|
||||
"Name": "tile",
|
||||
"Type": "Floor",
|
||||
"Style": "dirt",
|
||||
"Mask": "584418ff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": true,
|
||||
"IsOpaque": false,
|
||||
|
@@ -9,8 +9,7 @@
|
||||
},
|
||||
"Body": "demon",
|
||||
"Sounds": "ogre",
|
||||
"BloodColor": "ff0000",
|
||||
"HasHair": true
|
||||
"BloodColor": "ff0000"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -1,24 +1,17 @@
|
||||
{
|
||||
"Version": 2,
|
||||
"Order": [
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"],
|
||||
["gun_l", "legs", "body", "head", "hair", "gun_r"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "hair", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "hair", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head", "hair"]
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"],
|
||||
["gun_l", "legs", "body", "head", "gun_r"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "body", "head", "gun_r", "gun_l"],
|
||||
["legs", "gun_r", "body", "head", "gun_l"],
|
||||
["gun_r", "gun_l", "legs", "body", "head"]
|
||||
],
|
||||
"Offsets": {
|
||||
"Frame": {
|
||||
"Hair": {
|
||||
"stand": [[0, 10]],
|
||||
"idle": [[0, 10]],
|
||||
"run": [
|
||||
[0, 11], [0, 10], [0, 9], [0, 10], [0, 11], [0, 10], [0, 9], [0, 10]
|
||||
]
|
||||
},
|
||||
"Head": {
|
||||
"stand": [[0, 10]],
|
||||
"idle": [[0, 10]],
|
||||
@@ -41,9 +34,6 @@
|
||||
}
|
||||
},
|
||||
"Dir": {
|
||||
"Hair": [
|
||||
[0, -2], [2, -1], [4, 0], [2, 1], [0, 2], [-2, 1], [-4, 0], [-2, -1]
|
||||
],
|
||||
"Head": [
|
||||
[0, -2], [2, -1], [4, 0], [2, 1], [0, 2], [-2, 1], [-4, 0], [-2, -1]
|
||||
],
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (c) 2013-2020 Cong Xu
|
||||
Copyright (c) 2013-2020, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -54,6 +54,12 @@ color_t *CharColorGetByType(CharColors *c, const CharColorType t)
|
||||
return &c->Hair;
|
||||
case CHAR_COLOR_FEET:
|
||||
return &c->Feet;
|
||||
case CHAR_COLOR_FACEHAIR:
|
||||
return &c->Facehair;
|
||||
case CHAR_COLOR_HAT:
|
||||
return &c->Hat;
|
||||
case CHAR_COLOR_GLASSES:
|
||||
return &c->Glasses;
|
||||
default:
|
||||
CASSERT(false, "Unexpected colour");
|
||||
return &c->Skin;
|
||||
@@ -75,7 +81,7 @@ color_t *CharColorGetByType(CharColors *c, const CharColorType t)
|
||||
|
||||
uint8_t CharColorTypeAlpha(const CharColorType t)
|
||||
{
|
||||
static uint8_t alphas[] = {254, 253, 252, 251, 250, 249};
|
||||
static uint8_t alphas[] = {254, 253, 252, 251, 250, 249, 248, 247, 246};
|
||||
if (t < CHAR_COLOR_COUNT)
|
||||
{
|
||||
return alphas[t];
|
||||
@@ -83,7 +89,7 @@ uint8_t CharColorTypeAlpha(const CharColorType t)
|
||||
return 255;
|
||||
}
|
||||
#define CHAR_COLOR_THRESHOLD 5
|
||||
CharColorType CharColorTypeFromColor(const color_t c)
|
||||
CharColorType CharColorTypeFromColor(const color_t c, const CharColorType headPartColor)
|
||||
{
|
||||
if (abs((int)c.r - c.g) < CHAR_COLOR_THRESHOLD &&
|
||||
abs((int)c.g - c.b) < CHAR_COLOR_THRESHOLD &&
|
||||
@@ -99,8 +105,8 @@ CharColorType CharColorTypeFromColor(const color_t c)
|
||||
}
|
||||
else if ((c.r < 5 && c.b < 5) || (abs((int)c.r - c.b) < 5 && c.g > 250))
|
||||
{
|
||||
// Hair (G)
|
||||
return CHAR_COLOR_HAIR;
|
||||
// Head parts (G)
|
||||
return headPartColor;
|
||||
}
|
||||
else if ((c.r < 5 && c.g < 5) || (abs((int)c.r - c.g) < 5 && c.b > 250))
|
||||
{
|
||||
@@ -127,7 +133,7 @@ CharColorType CharColorTypeFromColor(const color_t c)
|
||||
}
|
||||
CharColors CharColorsFromOneColor(const color_t color)
|
||||
{
|
||||
CharColors c = {color, color, color, color, color, color};
|
||||
CharColors c = {color, color, color, color, color, color, color, color, color};
|
||||
return c;
|
||||
}
|
||||
color_t CharColorsGetChannelMask(const CharColors *c, const uint8_t alpha)
|
||||
@@ -148,6 +154,12 @@ color_t CharColorsGetChannelMask(const CharColors *c, const uint8_t alpha)
|
||||
return c->Hair;
|
||||
case 249:
|
||||
return c->Feet;
|
||||
case 248:
|
||||
return c->Facehair;
|
||||
case 247:
|
||||
return c->Hat;
|
||||
case 246:
|
||||
return c->Glasses;
|
||||
default:
|
||||
return colorWhite;
|
||||
}
|
||||
@@ -156,16 +168,20 @@ void CharColorsGetMaskedName(char *buf, const char *base, const CharColors *c)
|
||||
{
|
||||
char bufSkin[COLOR_STR_BUF], bufArms[COLOR_STR_BUF],
|
||||
bufBody[COLOR_STR_BUF], bufLegs[COLOR_STR_BUF], bufHair[COLOR_STR_BUF],
|
||||
bufFeet[COLOR_STR_BUF];
|
||||
bufFeet[COLOR_STR_BUF], bufFacehair[COLOR_STR_BUF], bufHat[COLOR_STR_BUF],
|
||||
bufGlasses[COLOR_STR_BUF];
|
||||
ColorStr(bufSkin, c->Skin);
|
||||
ColorStr(bufArms, c->Arms);
|
||||
ColorStr(bufBody, c->Body);
|
||||
ColorStr(bufLegs, c->Legs);
|
||||
ColorStr(bufHair, c->Hair);
|
||||
ColorStr(bufFeet, c->Feet);
|
||||
ColorStr(bufFacehair, c->Facehair);
|
||||
ColorStr(bufHat, c->Hat);
|
||||
ColorStr(bufGlasses, c->Glasses);
|
||||
sprintf(
|
||||
buf, "%s/%s/%s/%s/%s/%s/%s", base, bufSkin, bufArms, bufBody, bufLegs,
|
||||
bufHair, bufFeet);
|
||||
buf, "%s/%s/%s/%s/%s/%s/%s/%s/%s/%s", base, bufSkin, bufArms, bufBody, bufLegs,
|
||||
bufHair, bufFeet, bufFacehair, bufHat, bufGlasses);
|
||||
}
|
||||
|
||||
void BlitClearBuf(GraphicsDevice *g)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (c) 2013-2014, 2016-2020 Cong Xu
|
||||
Copyright (c) 2013-2014, 2016-2020, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -41,6 +41,9 @@ typedef struct
|
||||
color_t Legs;
|
||||
color_t Hair;
|
||||
color_t Feet;
|
||||
color_t Facehair;
|
||||
color_t Hat;
|
||||
color_t Glasses;
|
||||
} CharColors;
|
||||
typedef enum
|
||||
{
|
||||
@@ -50,6 +53,9 @@ typedef enum
|
||||
CHAR_COLOR_LEGS,
|
||||
CHAR_COLOR_HAIR,
|
||||
CHAR_COLOR_FEET,
|
||||
CHAR_COLOR_FACEHAIR,
|
||||
CHAR_COLOR_HAT,
|
||||
CHAR_COLOR_GLASSES,
|
||||
CHAR_COLOR_COUNT
|
||||
} CharColorType;
|
||||
color_t *CharColorGetByType(CharColors *c, const CharColorType t);
|
||||
@@ -59,7 +65,7 @@ void BlitFillBuf(GraphicsDevice *g, const color_t c);
|
||||
void BlitUpdateFromBuf(GraphicsDevice *g, SDL_Texture *t);
|
||||
|
||||
uint8_t CharColorTypeAlpha(const CharColorType t);
|
||||
CharColorType CharColorTypeFromColor(const color_t c);
|
||||
CharColorType CharColorTypeFromColor(const color_t c, const CharColorType headPartColor);
|
||||
CharColors CharColorsFromOneColor(const color_t color);
|
||||
color_t CharColorsGetChannelMask(const CharColors *c, const uint8_t alpha);
|
||||
void CharColorsGetMaskedName(char *buf, const char *base, const CharColors *c);
|
||||
|
@@ -35,7 +35,7 @@
|
||||
#include "json_utils.h"
|
||||
#include "player_template.h"
|
||||
|
||||
#define CHARACTER_VERSION 13
|
||||
#define CHARACTER_VERSION 14
|
||||
|
||||
static void CharacterInit(Character *c)
|
||||
{
|
||||
@@ -44,7 +44,10 @@ static void CharacterInit(Character *c)
|
||||
}
|
||||
static void CharacterTerminate(Character *c)
|
||||
{
|
||||
CFREE(c->Hair);
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
CFREE(c->HeadParts[hp]);
|
||||
}
|
||||
CFREE(c->bot);
|
||||
}
|
||||
|
||||
@@ -80,10 +83,12 @@ void CharacterStoreCopy(
|
||||
const CharBot *cb = c->bot;
|
||||
CMALLOC(c->bot, sizeof *c->bot);
|
||||
memcpy(c->bot, cb, sizeof *cb);
|
||||
const char *hair = c->Hair;
|
||||
if (hair != NULL)
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
CSTRDUP(c->Hair, hair);
|
||||
if (c->HeadParts[hp] != NULL)
|
||||
{
|
||||
CSTRDUP(c->HeadParts[hp], c->HeadParts[hp]);
|
||||
}
|
||||
}
|
||||
if (c->PlayerTemplateName != NULL)
|
||||
{
|
||||
@@ -130,7 +135,7 @@ void CharacterLoadJSON(
|
||||
tmp = GetString(child, "Class");
|
||||
}
|
||||
char *face = NULL;
|
||||
CharacterOldFaceToHair(tmp, &face, &ch->Hair);
|
||||
CharacterOldFaceToHeadParts(tmp, &face, ch->HeadParts);
|
||||
CFREE(tmp);
|
||||
ch->Class = StrCharacterClass(face);
|
||||
CFREE(face);
|
||||
@@ -141,8 +146,17 @@ void CharacterLoadJSON(
|
||||
ch->Class = StrCharacterClass(tmp);
|
||||
CFREE(tmp);
|
||||
tmp = NULL;
|
||||
LoadStr(&ch->Hair, child, "HairType");
|
||||
CFREE(tmp);
|
||||
LoadStr(&ch->HeadParts[HEAD_PART_HAIR], child, "HairType");
|
||||
if (version < 14)
|
||||
{
|
||||
CharacterOldHairToHeadParts(ch->HeadParts);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadStr(&ch->HeadParts[HEAD_PART_FACEHAIR], child, "FacehairType");
|
||||
LoadStr(&ch->HeadParts[HEAD_PART_HAT], child, "HatType");
|
||||
LoadStr(&ch->HeadParts[HEAD_PART_GLASSES], child, "GlassesType");
|
||||
}
|
||||
}
|
||||
CASSERT(ch->Class != NULL, "Cannot load character class");
|
||||
|
||||
@@ -167,14 +181,27 @@ void CharacterLoadJSON(
|
||||
LoadColor(&ch->Colors.Hair, child, "Hair");
|
||||
}
|
||||
ch->Colors.Feet = ch->Colors.Legs;
|
||||
if (version >= 13)
|
||||
{
|
||||
LoadColor(&ch->Colors.Feet, child, "Feet");
|
||||
}
|
||||
if (version < 12)
|
||||
if (version < 13)
|
||||
{
|
||||
ConvertHairColors(ch, ch->Class->Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadColor(&ch->Colors.Feet, child, "Feet");
|
||||
}
|
||||
if (version < 14)
|
||||
{
|
||||
ch->Colors.Facehair = ch->Colors.Hair;
|
||||
ch->Colors.Hat = ch->Colors.Hair;
|
||||
ch->Colors.Glasses = ch->Colors.Hair;
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadColor(&ch->Colors.Facehair, child, "Facehair");
|
||||
LoadColor(&ch->Colors.Hat, child, "Hat");
|
||||
LoadColor(&ch->Colors.Glasses, child, "Glasses");
|
||||
}
|
||||
|
||||
LoadStr(&ch->PlayerTemplateName, child, "PlayerTemplateName");
|
||||
LoadFullInt(&ch->speed, child, "speed");
|
||||
tmp = GetString(child, "Gun");
|
||||
@@ -221,9 +248,21 @@ bool CharacterSave(CharacterStore *s, const char *path)
|
||||
{
|
||||
AddStringPair(node, "PlayerTemplateName", c->PlayerTemplateName);
|
||||
}
|
||||
if (c->Hair)
|
||||
if (c->HeadParts[HEAD_PART_HAIR])
|
||||
{
|
||||
AddStringPair(node, "HairType", c->Hair);
|
||||
AddStringPair(node, "HairType", c->HeadParts[HEAD_PART_HAIR]);
|
||||
}
|
||||
if (c->HeadParts[HEAD_PART_FACEHAIR])
|
||||
{
|
||||
AddStringPair(node, "FacehairType", c->HeadParts[HEAD_PART_FACEHAIR]);
|
||||
}
|
||||
if (c->HeadParts[HEAD_PART_HAT])
|
||||
{
|
||||
AddStringPair(node, "HatType", c->HeadParts[HEAD_PART_HAT]);
|
||||
}
|
||||
if (c->HeadParts[HEAD_PART_GLASSES])
|
||||
{
|
||||
AddStringPair(node, "GlassesType", c->HeadParts[HEAD_PART_GLASSES]);
|
||||
}
|
||||
AddColorPair(node, "Skin", c->Colors.Skin);
|
||||
AddColorPair(node, "Arms", c->Colors.Arms);
|
||||
@@ -231,6 +270,9 @@ bool CharacterSave(CharacterStore *s, const char *path)
|
||||
AddColorPair(node, "Legs", c->Colors.Legs);
|
||||
AddColorPair(node, "Hair", c->Colors.Hair);
|
||||
AddColorPair(node, "Feet", c->Colors.Feet);
|
||||
AddColorPair(node, "Facehair", c->Colors.Facehair);
|
||||
AddColorPair(node, "Hat", c->Colors.Hat);
|
||||
AddColorPair(node, "Glasses", c->Colors.Glasses);
|
||||
AddIntPair(node, "speed", (int)(c->speed * 256));
|
||||
json_insert_pair_into_object(node, "Gun", json_new_string(c->Gun->name));
|
||||
AddIntPair(node, "maxHealth", c->maxHealth);
|
||||
@@ -332,6 +374,16 @@ bool CharacterIsPrisoner(const CharacterStore *store, const Character *c)
|
||||
return false;
|
||||
}
|
||||
|
||||
void CharacterSetHeadPart(Character *c, const HeadPart hp, const char *name)
|
||||
{
|
||||
CFREE(c->HeadParts[hp]);
|
||||
c->HeadParts[hp] = NULL;
|
||||
if (name)
|
||||
{
|
||||
CSTRDUP(c->HeadParts[hp], name);
|
||||
}
|
||||
}
|
||||
|
||||
static color_t RandomColor(void);
|
||||
void CharacterShuffleAppearance(Character *c)
|
||||
{
|
||||
@@ -349,16 +401,26 @@ void CharacterShuffleAppearance(Character *c)
|
||||
&gCharacterClasses.CustomClasses,
|
||||
charClass - gCharacterClasses.Classes.size);
|
||||
}
|
||||
CFREE(c->Hair);
|
||||
const char *hairStyleName = *(char **)CArrayGet(
|
||||
&gPicManager.hairstyleNames, rand() % gPicManager.hairstyleNames.size);
|
||||
CSTRDUP(c->Hair, hairStyleName);
|
||||
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
if (RAND_BOOL())
|
||||
{
|
||||
const CArray *hpNames = &gPicManager.headPartNames[hp];
|
||||
const char *name = *(char **)CArrayGet(hpNames, rand() % hpNames->size);
|
||||
CharacterSetHeadPart(c, hp, name);
|
||||
}
|
||||
}
|
||||
|
||||
c->Colors.Skin = RandomColor();
|
||||
c->Colors.Arms = RandomColor();
|
||||
c->Colors.Body = RandomColor();
|
||||
c->Colors.Legs = RandomColor();
|
||||
c->Colors.Hair = RandomColor();
|
||||
c->Colors.Feet = RandomColor();
|
||||
c->Colors.Facehair = c->Colors.Hair;
|
||||
c->Colors.Hat = RandomColor();
|
||||
c->Colors.Glasses = RandomColor();
|
||||
}
|
||||
static color_t RandomColor(void)
|
||||
{
|
||||
|
@@ -46,7 +46,7 @@ typedef struct
|
||||
{
|
||||
const CharacterClass *Class;
|
||||
char *PlayerTemplateName;
|
||||
char *Hair;
|
||||
char *HeadParts[HEAD_PART_COUNT];
|
||||
float speed;
|
||||
const WeaponClass *Gun;
|
||||
int maxHealth;
|
||||
@@ -89,4 +89,5 @@ int CharacterStoreGetRandomSpecialId(const CharacterStore *store);
|
||||
|
||||
bool CharacterIsPrisoner(const CharacterStore *store, const Character *c);
|
||||
|
||||
void CharacterSetHeadPart(Character *c, const HeadPart hp, const char *name);
|
||||
void CharacterShuffleAppearance(Character *c);
|
||||
|
@@ -2,7 +2,7 @@
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
|
||||
Copyright (c) 2016-2017, 2019-2021 Cong Xu
|
||||
Copyright (c) 2016-2017, 2019-2021, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -62,103 +62,107 @@ const char *IntCharacterFace(const int face)
|
||||
{
|
||||
return characterNames[face];
|
||||
}
|
||||
void CharacterOldFaceToHair(const char *face, char **newFace, char **hair)
|
||||
void CharacterOldFaceToHeadParts(const char *face, char **newFace, char *headParts[HEAD_PART_COUNT])
|
||||
{
|
||||
// Convert old faces to face + hair
|
||||
if (strcmp(face, "Bob") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Jones");
|
||||
CSTRDUP(*hair, "beard");
|
||||
CSTRDUP(headParts[HEAD_PART_HAIR], "flattop");
|
||||
CSTRDUP(headParts[HEAD_PART_FACEHAIR], "beard");
|
||||
}
|
||||
else if (strcmp(face, "Cyber Jones") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Cyborg");
|
||||
CSTRDUP(*hair, "cyber_shades");
|
||||
CSTRDUP(headParts[HEAD_PART_GLASSES], "cyber_shades");
|
||||
}
|
||||
else if (strcmp(face, "Cyber Smith") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Cyborg");
|
||||
CSTRDUP(*hair, "flattop");
|
||||
CSTRDUP(headParts[HEAD_PART_HAIR], "flattop");
|
||||
}
|
||||
else if (strcmp(face, "Cyber WarBaby") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Cyborg");
|
||||
CSTRDUP(*hair, "beret");
|
||||
CSTRDUP(headParts[HEAD_PART_HAT], "beret");
|
||||
}
|
||||
else if (strcmp(face, "Cyborg") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Cyborg");
|
||||
CSTRDUP(*hair, "cyborg");
|
||||
CSTRDUP(headParts[HEAD_PART_GLASSES], "cyborg");
|
||||
}
|
||||
else if (strcmp(face, "Dragon") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Jones");
|
||||
CSTRDUP(*hair, "hogan");
|
||||
CSTRDUP(headParts[HEAD_PART_HAIR], "rattail");
|
||||
CSTRDUP(headParts[HEAD_PART_FACEHAIR], "handlebar");
|
||||
}
|
||||
else if (strcmp(face, "Evil Ogre") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Ogre");
|
||||
CSTRDUP(*hair, "horns");
|
||||
CSTRDUP(headParts[HEAD_PART_HAT], "horns");
|
||||
}
|
||||
else if (strcmp(face, "Freeze") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Jones");
|
||||
CSTRDUP(*hair, "ski_goggles");
|
||||
CSTRDUP(headParts[HEAD_PART_GLASSES], "ski_goggles");
|
||||
}
|
||||
else if (strcmp(face, "Goggles") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Jones");
|
||||
CSTRDUP(*hair, "goggles");
|
||||
CSTRDUP(headParts[HEAD_PART_GLASSES], "goggles");
|
||||
}
|
||||
else if (strcmp(face, "Grunt") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Jones");
|
||||
CSTRDUP(*hair, "riot_helmet");
|
||||
CSTRDUP(headParts[HEAD_PART_HAT], "riot_helmet");
|
||||
}
|
||||
else if (strcmp(face, "Ice") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Jones");
|
||||
CSTRDUP(*hair, "shades");
|
||||
CSTRDUP(headParts[HEAD_PART_GLASSES], "shades");
|
||||
}
|
||||
else if (strcmp(face, "Lady") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Lady");
|
||||
CSTRDUP(*hair, "ponytail");
|
||||
CSTRDUP(headParts[HEAD_PART_HAIR], "ponytail");
|
||||
}
|
||||
else if (strcmp(face, "Ogre Boss") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Ogre");
|
||||
CSTRDUP(*hair, "mohawk");
|
||||
CSTRDUP(headParts[HEAD_PART_HAIR], "mohawk");
|
||||
}
|
||||
else if (strcmp(face, "Professor") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Jones");
|
||||
CSTRDUP(*hair, "professor");
|
||||
CSTRDUP(headParts[HEAD_PART_HAIR], "donut");
|
||||
CSTRDUP(headParts[HEAD_PART_GLASSES], "goggles");
|
||||
}
|
||||
else if (strcmp(face, "Smith") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Jones");
|
||||
CSTRDUP(*hair, "flattop");
|
||||
CSTRDUP(headParts[HEAD_PART_HAIR], "flattop");
|
||||
}
|
||||
else if (strcmp(face, "Snake") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Jones");
|
||||
CSTRDUP(*hair, "eye_patch");
|
||||
CSTRDUP(headParts[HEAD_PART_GLASSES], "eye_patch");
|
||||
}
|
||||
else if (strcmp(face, "Sweeper") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Jones");
|
||||
CSTRDUP(*hair, "helmet");
|
||||
CSTRDUP(headParts[HEAD_PART_HAT], "helmet");
|
||||
}
|
||||
else if (strcmp(face, "WarBaby") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Jones");
|
||||
CSTRDUP(*hair, "beret");
|
||||
CSTRDUP(headParts[HEAD_PART_HAT], "beret");
|
||||
}
|
||||
else if (strcmp(face, "Wolf") == 0)
|
||||
{
|
||||
CSTRDUP(*newFace, "Jones");
|
||||
CSTRDUP(*hair, "dutch");
|
||||
CSTRDUP(headParts[HEAD_PART_HAIR], "widows");
|
||||
CSTRDUP(headParts[HEAD_PART_FACEHAIR], "dutch");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -166,6 +170,112 @@ void CharacterOldFaceToHair(const char *face, char **newFace, char **hair)
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterOldHairToHeadParts(char *headParts[HEAD_PART_COUNT])
|
||||
{
|
||||
const char *hair = headParts[HEAD_PART_HAIR];
|
||||
if (hair == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (strcmp(hair, "beard") == 0)
|
||||
{
|
||||
CSTRDUP(headParts[HEAD_PART_HAIR], "flattop");
|
||||
CSTRDUP(headParts[HEAD_PART_FACEHAIR], "beard");
|
||||
}
|
||||
else if (strcmp(hair, "beret") == 0)
|
||||
{
|
||||
CFREE(headParts[HEAD_PART_HAIR]);
|
||||
headParts[HEAD_PART_HAIR] = NULL;
|
||||
CSTRDUP(headParts[HEAD_PART_HAT], "beret");
|
||||
}
|
||||
else if (strcmp(hair, "combat_helmet") == 0)
|
||||
{
|
||||
CFREE(headParts[HEAD_PART_HAIR]);
|
||||
headParts[HEAD_PART_HAIR] = NULL;
|
||||
CSTRDUP(headParts[HEAD_PART_HAT], "combat_helmet");
|
||||
}
|
||||
else if (strcmp(hair, "cyber_shades") == 0)
|
||||
{
|
||||
CFREE(headParts[HEAD_PART_HAIR]);
|
||||
headParts[HEAD_PART_HAIR] = NULL;
|
||||
CSTRDUP(headParts[HEAD_PART_GLASSES], "cyber_shades");
|
||||
}
|
||||
else if (strcmp(hair, "cyborg") == 0)
|
||||
{
|
||||
CFREE(headParts[HEAD_PART_HAIR]);
|
||||
headParts[HEAD_PART_HAIR] = NULL;
|
||||
CSTRDUP(headParts[HEAD_PART_GLASSES], "cyborg");
|
||||
}
|
||||
else if (strcmp(hair, "dutch") == 0)
|
||||
{
|
||||
CSTRDUP(headParts[HEAD_PART_HAIR], "widows");
|
||||
CSTRDUP(headParts[HEAD_PART_FACEHAIR], "dutch");
|
||||
}
|
||||
else if (strcmp(hair, "eye_patch") == 0)
|
||||
{
|
||||
CFREE(headParts[HEAD_PART_HAIR]);
|
||||
headParts[HEAD_PART_HAIR] = NULL;
|
||||
CSTRDUP(headParts[HEAD_PART_GLASSES], "eye_patch");
|
||||
}
|
||||
else if (strcmp(hair, "goggles") == 0)
|
||||
{
|
||||
CFREE(headParts[HEAD_PART_HAIR]);
|
||||
headParts[HEAD_PART_HAIR] = NULL;
|
||||
CSTRDUP(headParts[HEAD_PART_GLASSES], "goggles");
|
||||
}
|
||||
else if (strcmp(hair, "hazmat") == 0)
|
||||
{
|
||||
CFREE(headParts[HEAD_PART_HAIR]);
|
||||
headParts[HEAD_PART_HAIR] = NULL;
|
||||
CSTRDUP(headParts[HEAD_PART_HAT], "hazmat");
|
||||
}
|
||||
else if (strcmp(hair, "helmet") == 0)
|
||||
{
|
||||
CFREE(headParts[HEAD_PART_HAIR]);
|
||||
headParts[HEAD_PART_HAIR] = NULL;
|
||||
CSTRDUP(headParts[HEAD_PART_HAT], "helmet");
|
||||
}
|
||||
else if (strcmp(hair, "hogan") == 0)
|
||||
{
|
||||
CSTRDUP(headParts[HEAD_PART_HAIR], "rattail");
|
||||
CSTRDUP(headParts[HEAD_PART_FACEHAIR], "handlebar");
|
||||
}
|
||||
else if (strcmp(hair, "horns") == 0)
|
||||
{
|
||||
CFREE(headParts[HEAD_PART_HAIR]);
|
||||
headParts[HEAD_PART_HAIR] = NULL;
|
||||
CSTRDUP(headParts[HEAD_PART_HAT], "horns");
|
||||
}
|
||||
else if (strcmp(hair, "mad_doc") == 0)
|
||||
{
|
||||
CSTRDUP(headParts[HEAD_PART_HAIR], "donut");
|
||||
CSTRDUP(headParts[HEAD_PART_FACEHAIR], "beard");
|
||||
}
|
||||
else if (strcmp(hair, "peak_cap") == 0)
|
||||
{
|
||||
CFREE(headParts[HEAD_PART_HAIR]);
|
||||
headParts[HEAD_PART_HAIR] = NULL;
|
||||
CSTRDUP(headParts[HEAD_PART_HAT], "peak_cap");
|
||||
}
|
||||
else if (strcmp(hair, "professor") == 0)
|
||||
{
|
||||
CSTRDUP(headParts[HEAD_PART_HAIR], "donut");
|
||||
CSTRDUP(headParts[HEAD_PART_GLASSES], "goggles");
|
||||
}
|
||||
else if (strcmp(hair, "riot_helmet") == 0)
|
||||
{
|
||||
CFREE(headParts[HEAD_PART_HAIR]);
|
||||
headParts[HEAD_PART_HAIR] = NULL;
|
||||
CSTRDUP(headParts[HEAD_PART_HAT], "riot_helmet");
|
||||
}
|
||||
else if (strcmp(hair, "ski_goggles") == 0)
|
||||
{
|
||||
CFREE(headParts[HEAD_PART_HAIR]);
|
||||
headParts[HEAD_PART_HAIR] = NULL;
|
||||
CSTRDUP(headParts[HEAD_PART_GLASSES], "ski_goggles");
|
||||
}
|
||||
}
|
||||
|
||||
const NamedSprites *CharacterClassGetDeathSprites(const CharacterClass *c, const PicManager *pm)
|
||||
{
|
||||
char buf[256];
|
||||
@@ -293,8 +403,17 @@ static void LoadCharacterClass(CharacterClass *c, json_t *node)
|
||||
c->BloodColor = colorRed;
|
||||
LoadColor(&c->BloodColor, node, "BloodColor");
|
||||
|
||||
c->HasHair = true;
|
||||
LoadBool(&c->HasHair, node, "HasHair");
|
||||
// By default player classes allow cranial accessories
|
||||
// But some types can't/shouldn't have stuff like hair
|
||||
// For example the alien
|
||||
c->HasHeadParts[HEAD_PART_HAIR] = true;
|
||||
LoadBool(&c->HasHeadParts[HEAD_PART_HAIR], node, "HasHair");
|
||||
c->HasHeadParts[HEAD_PART_FACEHAIR] = true;
|
||||
LoadBool(&c->HasHeadParts[HEAD_PART_FACEHAIR], node, "HasFacehair");
|
||||
c->HasHeadParts[HEAD_PART_HAT] = true;
|
||||
LoadBool(&c->HasHeadParts[HEAD_PART_HAT], node, "HasHat");
|
||||
c->HasHeadParts[HEAD_PART_GLASSES] = true;
|
||||
LoadBool(&c->HasHeadParts[HEAD_PART_GLASSES], node, "HasGlasses");
|
||||
|
||||
LoadStr(&c->Corpse, node, "Corpse");
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
|
||||
Copyright (c) 2016-2021 Cong Xu
|
||||
Copyright (c) 2016-2021, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -48,7 +48,7 @@ typedef struct
|
||||
int FootstepsDistancePlus;
|
||||
color_t BloodColor;
|
||||
char *Corpse;
|
||||
bool HasHair;
|
||||
bool HasHeadParts[HEAD_PART_COUNT];
|
||||
} CharacterClass;
|
||||
typedef struct
|
||||
{
|
||||
@@ -62,7 +62,8 @@ extern CharacterClasses gCharacterClasses;
|
||||
const CharacterClass *StrCharacterClass(const char *s);
|
||||
// Legacy character class from "face" index
|
||||
const char *IntCharacterFace(const int face);
|
||||
void CharacterOldFaceToHair(const char *face, char **newFace, char **hair);
|
||||
void CharacterOldFaceToHeadParts(const char *face, char **newFace, char *headParts[HEAD_PART_COUNT]);
|
||||
void CharacterOldHairToHeadParts(char *headParts[HEAD_PART_COUNT]);
|
||||
const NamedSprites *CharacterClassGetDeathSprites(const CharacterClass *c, const PicManager *pm);
|
||||
const CharacterClass *IndexCharacterClass(const int i);
|
||||
int CharacterClassIndex(const CharacterClass *c);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (c) 2017, 2019-2020 Cong Xu
|
||||
Copyright (c) 2017, 2019-2020, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -130,16 +130,29 @@ static CharSprites *CharSpritesLoadJSON(const char *name, const char *path)
|
||||
for (direction_e d = DIRECTION_UP; d < DIRECTION_COUNT; d++)
|
||||
{
|
||||
const yajl_array orderDir = YAJL_GET_ARRAY(order->values[d]);
|
||||
int i = 0;
|
||||
for (BodyPart bp = BODY_PART_HEAD; bp < BODY_PART_COUNT; bp++)
|
||||
{
|
||||
c->Order[d][bp] =
|
||||
StrBodyPart(YAJL_GET_STRING(orderDir->values[bp]));
|
||||
StrBodyPart(YAJL_GET_STRING(orderDir->values[i]));
|
||||
i++;
|
||||
// Always draw head-parts in the following order:
|
||||
// head, facehair, glasses, hair, hat
|
||||
// Use the order for "head" and ignore the rest
|
||||
if (c->Order[d][bp] == BODY_PART_HEAD)
|
||||
{
|
||||
c->Order[d][++bp] = BODY_PART_FACEHAIR;
|
||||
c->Order[d][++bp] = BODY_PART_GLASSES;
|
||||
c->Order[d][++bp] = BODY_PART_HAIR;
|
||||
c->Order[d][++bp] = BODY_PART_HAT;
|
||||
}
|
||||
}
|
||||
}
|
||||
c->Offsets.Frame[BODY_PART_HEAD] =
|
||||
LoadFrameOffsets(node, "Offsets/Frame/Head");
|
||||
c->Offsets.Frame[BODY_PART_HAIR] =
|
||||
LoadFrameOffsets(node, "Offsets/Frame/Hair");
|
||||
// Use same offsets for head parts
|
||||
for (BodyPart bp = BODY_PART_HEAD; bp <= BODY_PART_GLASSES; bp++)
|
||||
{
|
||||
c->Offsets.Frame[bp] = LoadFrameOffsets(node, "Offsets/Frame/Head");
|
||||
}
|
||||
c->Offsets.Frame[BODY_PART_BODY] =
|
||||
LoadFrameOffsets(node, "Offsets/Frame/Body");
|
||||
c->Offsets.Frame[BODY_PART_LEGS] =
|
||||
@@ -149,7 +162,11 @@ static CharSprites *CharSpritesLoadJSON(const char *name, const char *path)
|
||||
c->Offsets.Frame[BODY_PART_GUN_L] =
|
||||
LoadFrameOffsets(node, "Offsets/Frame/Gun");
|
||||
LoadDirOffsets(c->Offsets.Dir[BODY_PART_HEAD], node, "Offsets/Dir/Head");
|
||||
LoadDirOffsets(c->Offsets.Dir[BODY_PART_HAIR], node, "Offsets/Dir/Hair");
|
||||
// Use same offsets for head parts
|
||||
for (BodyPart bp = BODY_PART_HEAD + 1; bp <= BODY_PART_GLASSES; bp++)
|
||||
{
|
||||
memcpy(&c->Offsets.Dir[bp], &c->Offsets.Dir[BODY_PART_HEAD], sizeof c->Offsets.Dir[bp]);
|
||||
}
|
||||
LoadDirOffsets(c->Offsets.Dir[BODY_PART_BODY], node, "Offsets/Dir/Body");
|
||||
LoadDirOffsets(c->Offsets.Dir[BODY_PART_LEGS], node, "Offsets/Dir/Legs");
|
||||
LoadDirOffsets(c->Offsets.Dir[BODY_PART_GUN_R], node, "Offsets/Dir/Gun");
|
||||
@@ -206,12 +223,22 @@ void CharSpriteClassesClear(map_t classes)
|
||||
{
|
||||
hashmap_destroy(classes, CharSpritesDestroy);
|
||||
}
|
||||
static void OffsetFrameDestroy(any_t data);
|
||||
static void CharSpritesDestroy(any_t data)
|
||||
{
|
||||
CharSprites *c = data;
|
||||
CFREE(c->Name);
|
||||
for (int i = 0; i < BODY_PART_COUNT + MAX_BARRELS - 1; i++)
|
||||
{
|
||||
hashmap_destroy(c->Offsets.Frame[i], OffsetFrameDestroy);
|
||||
}
|
||||
CFREE(c);
|
||||
}
|
||||
static void OffsetFrameDestroy(any_t data)
|
||||
{
|
||||
CArray *offsets = data;
|
||||
CArrayTerminate(offsets);
|
||||
}
|
||||
void CharSpriteClassesTerminate(CharSpriteClasses *c)
|
||||
{
|
||||
CharSpriteClassesClear(c->classes);
|
||||
|
@@ -22,7 +22,7 @@
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
|
||||
Copyright (c) 2013-2021 Cong Xu
|
||||
Copyright (c) 2013-2021, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -191,8 +191,7 @@ static void UpdatePilotHeadPic(
|
||||
return;
|
||||
}
|
||||
// If this is a vehicle, take the head/hair pic from the pilot
|
||||
pics->Head = NULL;
|
||||
pics->Hair = NULL;
|
||||
memset(&pics->HeadParts, 0, sizeof pics->HeadParts);
|
||||
const TActor *pilot = ActorGetByUID(a->pilotUID);
|
||||
if (pilot == NULL)
|
||||
{
|
||||
@@ -201,9 +200,13 @@ static void UpdatePilotHeadPic(
|
||||
const Character *c = ActorGetCharacter(pilot);
|
||||
const bool grimace = ActorIsGrimacing(a);
|
||||
pics->Head = GetHeadPic(c->Class, dir, grimace, &c->Colors);
|
||||
if (c->Class->HasHair)
|
||||
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
pics->Hair = GetHairPic(c->Hair, dir, grimace, &c->Colors);
|
||||
if (c->Class->HasHeadParts[hp])
|
||||
{
|
||||
pics->HeadParts[hp] = GetHeadPartPic(c->HeadParts[hp], hp, dir, grimace, &c->Colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
ActorPics GetCharacterPics(
|
||||
@@ -312,13 +315,17 @@ static ActorPics GetUnorderedPics(
|
||||
pics.HeadOffset = GetActorDrawOffset(
|
||||
pics.Head, BODY_PART_HEAD, c->Class->Sprites, anim, frame, dir,
|
||||
GUNSTATE_READY);
|
||||
if (c->Class->HasHair)
|
||||
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
pics.Hair = GetHairPic(c->Hair, headDir, grimace, colors);
|
||||
if (c->Class->HasHeadParts[hp])
|
||||
{
|
||||
pics.HeadParts[hp] = GetHeadPartPic(c->HeadParts[hp], hp, headDir, grimace, colors);
|
||||
pics.HeadPartOffsets[hp] = GetActorDrawOffset(
|
||||
pics.HeadParts[hp], BODY_PART_HEAD, c->Class->Sprites, anim, frame, dir,
|
||||
GUNSTATE_READY);
|
||||
}
|
||||
}
|
||||
pics.HairOffset = GetActorDrawOffset(
|
||||
pics.Hair, BODY_PART_HAIR, c->Class->Sprites, anim, frame, dir,
|
||||
GUNSTATE_READY);
|
||||
|
||||
// Gun
|
||||
for (int i = 0; i < numBarrels; i++)
|
||||
@@ -399,8 +406,20 @@ static void ReorderPics(
|
||||
pics->OrderedOffsets[bp] = pics->HeadOffset;
|
||||
break;
|
||||
case BODY_PART_HAIR:
|
||||
pics->OrderedPics[bp] = pics->Hair;
|
||||
pics->OrderedOffsets[bp] = pics->HairOffset;
|
||||
pics->OrderedPics[bp] = pics->HeadParts[HEAD_PART_HAIR];
|
||||
pics->OrderedOffsets[bp] = pics->HeadPartOffsets[HEAD_PART_HAIR];
|
||||
break;
|
||||
case BODY_PART_FACEHAIR:
|
||||
pics->OrderedPics[bp] = pics->HeadParts[HEAD_PART_FACEHAIR];
|
||||
pics->OrderedOffsets[bp] = pics->HeadPartOffsets[HEAD_PART_FACEHAIR];
|
||||
break;
|
||||
case BODY_PART_HAT:
|
||||
pics->OrderedPics[bp] = pics->HeadParts[HEAD_PART_HAT];
|
||||
pics->OrderedOffsets[bp] = pics->HeadPartOffsets[HEAD_PART_HAT];
|
||||
break;
|
||||
case BODY_PART_GLASSES:
|
||||
pics->OrderedPics[bp] = pics->HeadParts[HEAD_PART_GLASSES];
|
||||
pics->OrderedOffsets[bp] = pics->HeadPartOffsets[HEAD_PART_GLASSES];
|
||||
break;
|
||||
case BODY_PART_BODY:
|
||||
pics->OrderedPics[bp] = pics->Body;
|
||||
@@ -538,11 +557,11 @@ const Pic *GetHeadPic(
|
||||
PicManagerGetCharSprites(&gPicManager, c->HeadSprites, colors);
|
||||
return CArrayGet(&ns->pics, idx);
|
||||
}
|
||||
const Pic *GetHairPic(
|
||||
const char *hair, const direction_e dir, const bool isGrimacing,
|
||||
const Pic *GetHeadPartPic(
|
||||
const char *name, const HeadPart hp, const direction_e dir, const bool isGrimacing,
|
||||
const CharColors *colors)
|
||||
{
|
||||
if (hair == NULL)
|
||||
if (name == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -550,7 +569,8 @@ const Pic *GetHairPic(
|
||||
const int idx = (int)dir + row * 8;
|
||||
// Get or generate masked sprites
|
||||
char buf[CDOGS_PATH_MAX];
|
||||
sprintf(buf, "chars/hairs/%s", hair);
|
||||
const char *subpaths[] = {"hairs", "facehairs", "hats", "glasses"};
|
||||
sprintf(buf, "chars/%s/%s", subpaths[hp], name);
|
||||
const NamedSprites *ns =
|
||||
PicManagerGetCharSprites(&gPicManager, buf, colors);
|
||||
return CArrayGet(&ns->pics, idx);
|
||||
@@ -665,14 +685,18 @@ void DrawHead(
|
||||
PicRender(
|
||||
head, renderer, drawPos, mask, 0, svec2_one(), SDL_FLIP_NONE,
|
||||
Rect2iZero());
|
||||
if (c->Class->HasHair)
|
||||
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
const Pic *hair = GetHairPic(c->Hair, dir, isGrimacing, &c->Colors);
|
||||
if (hair)
|
||||
if (c->Class->HasHeadParts[hp])
|
||||
{
|
||||
PicRender(
|
||||
hair, renderer, drawPos, mask, 0, svec2_one(), SDL_FLIP_NONE,
|
||||
Rect2iZero());
|
||||
const Pic *pic = GetHeadPartPic(c->HeadParts[hp], hp, dir, isGrimacing, &c->Colors);
|
||||
if (pic)
|
||||
{
|
||||
PicRender(
|
||||
pic, renderer, drawPos, mask, 0, svec2_one(), SDL_FLIP_NONE,
|
||||
Rect2iZero());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,7 @@
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
|
||||
Copyright (c) 2013-2014, 2016-2021 Cong Xu
|
||||
Copyright (c) 2013-2014, 2016-2021, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -56,9 +56,9 @@
|
||||
typedef struct
|
||||
{
|
||||
const Pic *Head;
|
||||
struct vec2i HairOffset;
|
||||
const Pic *Hair;
|
||||
struct vec2i HeadOffset;
|
||||
const Pic *HeadParts[HEAD_PART_COUNT];
|
||||
struct vec2i HeadPartOffsets[HEAD_PART_COUNT];
|
||||
const Pic *Body;
|
||||
struct vec2i BodyOffset;
|
||||
const Pic *Legs;
|
||||
@@ -85,8 +85,8 @@ void DrawHead(
|
||||
const Pic *GetHeadPic(
|
||||
const CharacterClass *c, const direction_e dir, const bool isGrimacing,
|
||||
const CharColors *colors);
|
||||
const Pic *GetHairPic(
|
||||
const char *hair, const direction_e dir, const bool isGrimacing,
|
||||
const Pic *GetHeadPartPic(
|
||||
const char *name, const HeadPart hp, const direction_e dir, const bool isGrimacing,
|
||||
const CharColors *colors);
|
||||
ActorPics GetCharacterPics(
|
||||
const Character *c, const direction_e dir, const direction_e legDir,
|
||||
|
@@ -286,6 +286,7 @@ void ConvertCharacterColors(
|
||||
c->Legs = ColorTint(PaletteToColor(cShadePalettes[leg]), tint);
|
||||
c->Hair = ColorTint(PaletteToColor(cShadePalettes[hair]), tint);
|
||||
c->Feet = c->Legs;
|
||||
c->Facehair = c->Hat = c->Glasses = c->Hair;
|
||||
}
|
||||
|
||||
// Hair colour correction; some characters had no hair but now with
|
||||
@@ -344,7 +345,7 @@ void ConvertCharacter(Character *c, TBadGuy *b)
|
||||
{
|
||||
const char *face = IntCharacterFace(b->facePic);
|
||||
char *newFace = NULL;
|
||||
CharacterOldFaceToHair(face, &newFace, &c->Hair);
|
||||
CharacterOldFaceToHeadParts(face, &newFace, c->HeadParts);
|
||||
c->Class = StrCharacterClass(newFace);
|
||||
CFREE(newFace);
|
||||
c->speed = b->speed / 256.0f;
|
||||
|
@@ -2,7 +2,7 @@
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
|
||||
Copyright (c) 2014-2016, 2020-2021 Cong Xu
|
||||
Copyright (c) 2014-2016, 2020-2021, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -63,9 +63,21 @@ NPlayerData NMakePlayerData(const PlayerData *p)
|
||||
const Character *c = &p->Char;
|
||||
strcpy(d.Name, p->name);
|
||||
strcpy(d.CharacterClass, p->Char.Class->Name);
|
||||
if (p->Char.Hair)
|
||||
if (p->Char.HeadParts[HEAD_PART_HAIR])
|
||||
{
|
||||
strcpy(d.Hair, p->Char.Hair);
|
||||
strcpy(d.Hair, p->Char.HeadParts[HEAD_PART_HAIR]);
|
||||
}
|
||||
if (p->Char.HeadParts[HEAD_PART_FACEHAIR])
|
||||
{
|
||||
strcpy(d.Facehair, p->Char.HeadParts[HEAD_PART_FACEHAIR]);
|
||||
}
|
||||
if (p->Char.HeadParts[HEAD_PART_HAT])
|
||||
{
|
||||
strcpy(d.Hat, p->Char.HeadParts[HEAD_PART_HAT]);
|
||||
}
|
||||
if (p->Char.HeadParts[HEAD_PART_GLASSES])
|
||||
{
|
||||
strcpy(d.Glasses, p->Char.HeadParts[HEAD_PART_GLASSES]);
|
||||
}
|
||||
d.Colors = CharColors2Net(c->Colors);
|
||||
d.Weapons_count = MAX_WEAPONS;
|
||||
@@ -143,13 +155,16 @@ NCharColors CharColors2Net(const CharColors c)
|
||||
{
|
||||
NCharColors co;
|
||||
co.has_Skin = co.has_Arms = co.has_Body = co.has_Legs = co.has_Hair =
|
||||
co.has_Feet = true;
|
||||
co.has_Feet = co.has_Facehair = co.has_Hat = co.has_Glasses = true;
|
||||
co.Skin = Color2Net(c.Skin);
|
||||
co.Arms = Color2Net(c.Arms);
|
||||
co.Body = Color2Net(c.Body);
|
||||
co.Legs = Color2Net(c.Legs);
|
||||
co.Hair = Color2Net(c.Hair);
|
||||
co.Feet = Color2Net(c.Feet);
|
||||
co.Facehair = Color2Net(c.Facehair);
|
||||
co.Hat = Color2Net(c.Hat);
|
||||
co.Glasses = Color2Net(c.Glasses);
|
||||
return co;
|
||||
}
|
||||
CharColors Net2CharColors(const NCharColors c)
|
||||
@@ -161,6 +176,9 @@ CharColors Net2CharColors(const NCharColors c)
|
||||
co.Legs = Net2Color(c.Legs);
|
||||
co.Hair = Net2Color(c.Hair);
|
||||
co.Feet = Net2Color(c.Feet);
|
||||
co.Facehair = Net2Color(c.Facehair);
|
||||
co.Hat = Net2Color(c.Hat);
|
||||
co.Glasses = Net2Color(c.Glasses);
|
||||
return co;
|
||||
}
|
||||
void Ammo2Net(pb_size_t *ammoCount, NAmmo *ammo, const CArray *a)
|
||||
|
@@ -40,7 +40,7 @@
|
||||
|
||||
#define NET_LISTEN_PORT 34219
|
||||
|
||||
#define NET_PROTOCOL_VERSION 13
|
||||
#define NET_PROTOCOL_VERSION 14
|
||||
|
||||
// Messages
|
||||
|
||||
|
@@ -54,7 +54,10 @@ void PicManagerInit(PicManager *pm)
|
||||
pm->sprites = hashmap_new();
|
||||
pm->customPics = hashmap_new();
|
||||
pm->customSprites = hashmap_new();
|
||||
CArrayInit(&pm->hairstyleNames, sizeof(char *));
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
CArrayInit(&pm->headPartNames[hp], sizeof(char *));
|
||||
}
|
||||
CArrayInit(&pm->wallStyleNames, sizeof(char *));
|
||||
CArrayInit(&pm->tileStyleNames, sizeof(char *));
|
||||
CArrayInit(&pm->exitStyleNames, sizeof(char *));
|
||||
@@ -135,6 +138,22 @@ static void PicManagerAdd(
|
||||
|
||||
if (strncmp("chars/", buf, strlen("chars/")) == 0)
|
||||
{
|
||||
// All head parts use hair color, so determine
|
||||
// which head part we are looking at
|
||||
const char *subfolder = buf + strlen("chars/");
|
||||
CharColorType headPartColor = CHAR_COLOR_HAIR;
|
||||
if (strncmp("facehairs/", subfolder, strlen("facehairs/")) == 0)
|
||||
{
|
||||
headPartColor = CHAR_COLOR_FACEHAIR;
|
||||
}
|
||||
else if (strncmp("hats/", subfolder, strlen("hats/")) == 0)
|
||||
{
|
||||
headPartColor = CHAR_COLOR_HAT;
|
||||
}
|
||||
else if (strncmp("glasses/", subfolder, strlen("glasses/")) == 0)
|
||||
{
|
||||
headPartColor = CHAR_COLOR_GLASSES;
|
||||
}
|
||||
// Convert char pics to multichannel version
|
||||
for (int i = 0; i < pic->size.x * pic->size.y; i++)
|
||||
{
|
||||
@@ -147,7 +166,7 @@ static void PicManagerAdd(
|
||||
}
|
||||
// Convert character color keyed color to
|
||||
// greyscale + special alpha
|
||||
const CharColorType colorType = CharColorTypeFromColor(c);
|
||||
const CharColorType colorType = CharColorTypeFromColor(c, headPartColor);
|
||||
color_t converted = c;
|
||||
if (colorType != CHAR_COLOR_COUNT)
|
||||
{
|
||||
@@ -249,7 +268,10 @@ static void FindStylePics(
|
||||
PicManager *pm, CArray *styleNames, PFany hashmapFunc);
|
||||
static void FindStyleSprites(
|
||||
PicManager *pm, CArray *styleNames, PFany hashmapFunc);
|
||||
static int MaybeAdHairSpriteName(any_t data, any_t item);
|
||||
static int MaybeAddHairSpriteName(any_t data, any_t item);
|
||||
static int MaybeAddFacehairSpriteName(any_t data, any_t item);
|
||||
static int MaybeAddHatSpriteName(any_t data, any_t item);
|
||||
static int MaybeAddGlassesSpriteName(any_t data, any_t item);
|
||||
static int MaybeAddWallPicName(any_t data, any_t item);
|
||||
static int MaybeAddTilePicName(any_t data, any_t item);
|
||||
static int MaybeAddExitPicName(any_t data, any_t item);
|
||||
@@ -257,7 +279,10 @@ static int MaybeAddKeyPicName(any_t data, any_t item);
|
||||
static int MaybeAddDoorPicName(any_t data, any_t item);
|
||||
static void AfterAdd(PicManager *pm)
|
||||
{
|
||||
FindStyleSprites(pm, &pm->hairstyleNames, MaybeAdHairSpriteName);
|
||||
FindStyleSprites(pm, &pm->headPartNames[HEAD_PART_HAIR], MaybeAddHairSpriteName);
|
||||
FindStyleSprites(pm, &pm->headPartNames[HEAD_PART_FACEHAIR], MaybeAddFacehairSpriteName);
|
||||
FindStyleSprites(pm, &pm->headPartNames[HEAD_PART_HAT], MaybeAddHatSpriteName);
|
||||
FindStyleSprites(pm, &pm->headPartNames[HEAD_PART_GLASSES], MaybeAddGlassesSpriteName);
|
||||
FindStylePics(pm, &pm->wallStyleNames, MaybeAddWallPicName);
|
||||
FindStylePics(pm, &pm->tileStyleNames, MaybeAddTilePicName);
|
||||
FindStylePics(pm, &pm->exitStyleNames, MaybeAddExitPicName);
|
||||
@@ -344,14 +369,30 @@ static void MaybeAddStyleName(
|
||||
CSTRDUP(s, buf);
|
||||
CArrayPushBack(styleNames, &s);
|
||||
}
|
||||
static int MaybeAdHairSpriteName(any_t data, any_t item)
|
||||
static int MaybeAddHeadPartSpriteName(any_t data, any_t item, const HeadPart hp, const char *path)
|
||||
{
|
||||
PicManager *pm = data;
|
||||
MaybeAddStyleName(
|
||||
((const NamedSprites *)item)->name, "chars/hairs/",
|
||||
&pm->hairstyleNames);
|
||||
((const NamedSprites *)item)->name, path,
|
||||
&pm->headPartNames[hp]);
|
||||
return MAP_OK;
|
||||
}
|
||||
static int MaybeAddHairSpriteName(any_t data, any_t item)
|
||||
{
|
||||
return MaybeAddHeadPartSpriteName(data, item, HEAD_PART_HAIR, "chars/hairs/");
|
||||
}
|
||||
static int MaybeAddFacehairSpriteName(any_t data, any_t item)
|
||||
{
|
||||
return MaybeAddHeadPartSpriteName(data, item, HEAD_PART_FACEHAIR, "chars/facehairs/");
|
||||
}
|
||||
static int MaybeAddHatSpriteName(any_t data, any_t item)
|
||||
{
|
||||
return MaybeAddHeadPartSpriteName(data, item, HEAD_PART_HAT, "chars/hats/");
|
||||
}
|
||||
static int MaybeAddGlassesSpriteName(any_t data, any_t item)
|
||||
{
|
||||
return MaybeAddHeadPartSpriteName(data, item, HEAD_PART_GLASSES, "chars/glasses/");
|
||||
}
|
||||
static int MaybeAddExitPicName(any_t data, any_t item)
|
||||
{
|
||||
// Exit pics should be like:
|
||||
@@ -434,7 +475,10 @@ static void StyleNamesDestroy(CArray *a)
|
||||
void PicManagerTerminate(PicManager *pm)
|
||||
{
|
||||
PicManagerUnload(pm);
|
||||
StyleNamesDestroy(&pm->hairstyleNames);
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
StyleNamesDestroy(&pm->headPartNames[hp]);
|
||||
}
|
||||
StyleNamesDestroy(&pm->wallStyleNames);
|
||||
StyleNamesDestroy(&pm->tileStyleNames);
|
||||
StyleNamesDestroy(&pm->exitStyleNames);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (c) 2013-2016, 2018-2019 Cong Xu
|
||||
Copyright (c) 2013-2016, 2018-2019, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -38,7 +38,7 @@ typedef struct
|
||||
map_t customPics; // of NamedPic
|
||||
map_t customSprites; // of NamedSprites
|
||||
|
||||
CArray hairstyleNames; // of char *
|
||||
CArray headPartNames[HEAD_PART_COUNT]; // of char *
|
||||
CArray wallStyleNames; // of char *
|
||||
CArray tileStyleNames; // of char *
|
||||
CArray exitStyleNames; // of char *
|
||||
|
@@ -74,12 +74,17 @@ void PlayerDataAddOrUpdate(const NPlayerData pd)
|
||||
{
|
||||
p->Char.Class = StrCharacterClass("Jones");
|
||||
}
|
||||
CFREE(p->Char.Hair);
|
||||
p->Char.Hair = NULL;
|
||||
if (strlen(pd.Hair) > 0)
|
||||
{
|
||||
CSTRDUP(p->Char.Hair, pd.Hair);
|
||||
#define ADDHEADPART(_hp, _pdPart) \
|
||||
CFREE(p->Char.HeadParts[_hp]); \
|
||||
p->Char.HeadParts[_hp] = NULL; \
|
||||
if (strlen(_pdPart) > 0) \
|
||||
{ \
|
||||
CSTRDUP(p->Char.HeadParts[_hp], _pdPart); \
|
||||
}
|
||||
ADDHEADPART(HEAD_PART_HAIR, pd.Hair);
|
||||
ADDHEADPART(HEAD_PART_FACEHAIR, pd.Facehair);
|
||||
ADDHEADPART(HEAD_PART_HAT, pd.Hat);
|
||||
ADDHEADPART(HEAD_PART_GLASSES, pd.Glasses);
|
||||
p->Char.Colors = Net2CharColors(pd.Colors);
|
||||
for (int i = 0; i < (int)pd.Weapons_count; i++)
|
||||
{
|
||||
@@ -155,9 +160,21 @@ NPlayerData PlayerDataDefault(const int idx)
|
||||
{
|
||||
strcpy(pd.Name, t->name);
|
||||
strcpy(pd.CharacterClass, t->CharClassName);
|
||||
if (t->Hair != NULL)
|
||||
if (t->HeadParts[HEAD_PART_HAIR] != NULL)
|
||||
{
|
||||
strcpy(pd.Hair, t->Hair);
|
||||
strcpy(pd.Hair, t->HeadParts[HEAD_PART_HAIR]);
|
||||
}
|
||||
if (t->HeadParts[HEAD_PART_FACEHAIR] != NULL)
|
||||
{
|
||||
strcpy(pd.Facehair, t->HeadParts[HEAD_PART_FACEHAIR]);
|
||||
}
|
||||
if (t->HeadParts[HEAD_PART_HAT] != NULL)
|
||||
{
|
||||
strcpy(pd.Hat, t->HeadParts[HEAD_PART_HAT]);
|
||||
}
|
||||
if (t->HeadParts[HEAD_PART_GLASSES] != NULL)
|
||||
{
|
||||
strcpy(pd.Glasses, t->HeadParts[HEAD_PART_GLASSES]);
|
||||
}
|
||||
pd.Colors = CharColors2Net(t->Colors);
|
||||
}
|
||||
@@ -172,41 +189,42 @@ NPlayerData PlayerDataDefault(const int idx)
|
||||
pd.Colors.Arms = Color2Net(colorLightBlue);
|
||||
pd.Colors.Body = Color2Net(colorLightBlue);
|
||||
pd.Colors.Legs = Color2Net(colorLightBlue);
|
||||
pd.Colors.Hair = Color2Net(colorLightBlue);
|
||||
pd.Colors.Feet = Color2Net(colorLightBlue);
|
||||
break;
|
||||
case 1:
|
||||
strcpy(pd.Name, "Ice");
|
||||
strcpy(pd.CharacterClass, "Jones");
|
||||
strcpy(pd.Hair, "shades");
|
||||
strcpy(pd.Glasses, "shades");
|
||||
pd.Colors.Skin = Color2Net(colorDarkSkin);
|
||||
pd.Colors.Arms = Color2Net(colorRed);
|
||||
pd.Colors.Body = Color2Net(colorRed);
|
||||
pd.Colors.Legs = Color2Net(colorRed);
|
||||
pd.Colors.Hair = Color2Net(colorBlack);
|
||||
pd.Colors.Feet = Color2Net(colorRed);
|
||||
pd.Colors.Glasses = Color2Net(colorBlack);
|
||||
break;
|
||||
case 2:
|
||||
strcpy(pd.Name, "Warbaby");
|
||||
strcpy(pd.CharacterClass, "Jones");
|
||||
strcpy(pd.Hair, "beret");
|
||||
strcpy(pd.Hat, "beret");
|
||||
pd.Colors.Skin = Color2Net(colorSkin);
|
||||
pd.Colors.Arms = Color2Net(colorGreen);
|
||||
pd.Colors.Body = Color2Net(colorGreen);
|
||||
pd.Colors.Legs = Color2Net(colorGreen);
|
||||
pd.Colors.Hair = Color2Net(colorRed);
|
||||
pd.Colors.Feet = Color2Net(colorGreen);
|
||||
pd.Colors.Hat = Color2Net(colorRed);
|
||||
break;
|
||||
case 3:
|
||||
strcpy(pd.Name, "Han");
|
||||
strcpy(pd.CharacterClass, "Jones");
|
||||
strcpy(pd.Hair, "hogan");
|
||||
strcpy(pd.Hair, "rattail");
|
||||
strcpy(pd.Facehair, "handlebar");
|
||||
pd.Colors.Skin = Color2Net(colorAsianSkin);
|
||||
pd.Colors.Arms = Color2Net(colorYellow);
|
||||
pd.Colors.Body = Color2Net(colorYellow);
|
||||
pd.Colors.Legs = Color2Net(colorYellow);
|
||||
pd.Colors.Hair = Color2Net(colorYellow);
|
||||
pd.Colors.Feet = Color2Net(colorYellow);
|
||||
pd.Colors.Facehair = Color2Net(colorYellow);
|
||||
break;
|
||||
default:
|
||||
// Set up player N template
|
||||
|
@@ -2,7 +2,7 @@
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
|
||||
Copyright (c) 2013-2014, 2016-2020 Cong Xu
|
||||
Copyright (c) 2013-2014, 2016-2020, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#define VERSION 3
|
||||
#define VERSION 4
|
||||
|
||||
PlayerTemplates gPlayerTemplates;
|
||||
|
||||
@@ -57,12 +57,22 @@ static void LoadPlayerTemplate(
|
||||
{
|
||||
char *face;
|
||||
CSTRDUP(face, t.CharClassName);
|
||||
CharacterOldFaceToHair(t.CharClassName, &t.CharClassName, &t.Hair);
|
||||
CharacterOldFaceToHeadParts(t.CharClassName, &t.CharClassName, t.HeadParts);
|
||||
CFREE(face);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadStr(&t.Hair, node, "HairType");
|
||||
LoadStr(&t.HeadParts[HEAD_PART_HAIR], node, "HairType");
|
||||
if (version < 4)
|
||||
{
|
||||
CharacterOldHairToHeadParts(t.HeadParts);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadStr(&t.HeadParts[HEAD_PART_FACEHAIR], node, "FacehairType");
|
||||
LoadStr(&t.HeadParts[HEAD_PART_HAT], node, "HatType");
|
||||
LoadStr(&t.HeadParts[HEAD_PART_GLASSES], node, "GlassesType");
|
||||
}
|
||||
}
|
||||
// Colors
|
||||
if (version == 1)
|
||||
@@ -84,11 +94,19 @@ static void LoadPlayerTemplate(
|
||||
LoadColor(&t.Colors.Legs, node, "Legs");
|
||||
LoadColor(&t.Colors.Hair, node, "Hair");
|
||||
}
|
||||
t.Colors.Feet = t.Colors.Legs;
|
||||
if (version >= 3)
|
||||
if (version < 3)
|
||||
{
|
||||
LoadColor(&t.Colors.Feet, node, "Feet");
|
||||
t.Colors.Feet = t.Colors.Legs;
|
||||
}
|
||||
LoadColor(&t.Colors.Feet, node, "Feet");
|
||||
if (version < 4)
|
||||
{
|
||||
t.Colors.Facehair = t.Colors.Hat = t.Colors.Glasses = t.Colors.Hair;
|
||||
}
|
||||
LoadColor(&t.Colors.Facehair, node, "Facehair");
|
||||
LoadColor(&t.Colors.Hat, node, "Hat");
|
||||
LoadColor(&t.Colors.Glasses, node, "Glasses");
|
||||
|
||||
CArrayPushBack(templates, &t);
|
||||
LOG(LM_MAIN, LL_DEBUG, "loaded player template %s (%s)", t.name,
|
||||
t.CharClassName);
|
||||
@@ -152,7 +170,10 @@ void PlayerTemplatesClear(CArray *classes)
|
||||
{
|
||||
CA_FOREACH(PlayerTemplate, pt, *classes)
|
||||
CFREE(pt->CharClassName);
|
||||
CFREE(pt->Hair);
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
CFREE(pt->HeadParts[hp]);
|
||||
}
|
||||
CA_FOREACH_END()
|
||||
CArrayClear(classes);
|
||||
}
|
||||
@@ -180,16 +201,35 @@ PlayerTemplate *PlayerTemplateGetById(PlayerTemplates *pt, const int id)
|
||||
|
||||
static void SavePlayerTemplate(const PlayerTemplate *t, json_t *templates)
|
||||
{
|
||||
json_t *template = json_new_object();
|
||||
AddStringPair(template, "Name", t->name);
|
||||
AddStringPair(template, "Face", t->CharClassName);
|
||||
AddColorPair(template, "Body", t->Colors.Body);
|
||||
AddColorPair(template, "Arms", t->Colors.Arms);
|
||||
AddColorPair(template, "Legs", t->Colors.Legs);
|
||||
AddColorPair(template, "Skin", t->Colors.Skin);
|
||||
AddColorPair(template, "Hair", t->Colors.Hair);
|
||||
AddColorPair(template, "Feet", t->Colors.Feet);
|
||||
json_insert_child(templates, template);
|
||||
json_t *node = json_new_object();
|
||||
AddStringPair(node, "Name", t->name);
|
||||
AddStringPair(node, "Face", t->CharClassName);
|
||||
if (t->HeadParts[HEAD_PART_HAIR])
|
||||
{
|
||||
AddStringPair(node, "HairType", t->HeadParts[HEAD_PART_HAIR]);
|
||||
}
|
||||
if (t->HeadParts[HEAD_PART_FACEHAIR])
|
||||
{
|
||||
AddStringPair(node, "FacehairType", t->HeadParts[HEAD_PART_FACEHAIR]);
|
||||
}
|
||||
if (t->HeadParts[HEAD_PART_HAT])
|
||||
{
|
||||
AddStringPair(node, "HatType", t->HeadParts[HEAD_PART_HAT]);
|
||||
}
|
||||
if (t->HeadParts[HEAD_PART_GLASSES])
|
||||
{
|
||||
AddStringPair(node, "GlassesType", t->HeadParts[HEAD_PART_GLASSES]);
|
||||
}
|
||||
AddColorPair(node, "Body", t->Colors.Body);
|
||||
AddColorPair(node, "Arms", t->Colors.Arms);
|
||||
AddColorPair(node, "Legs", t->Colors.Legs);
|
||||
AddColorPair(node, "Skin", t->Colors.Skin);
|
||||
AddColorPair(node, "Hair", t->Colors.Hair);
|
||||
AddColorPair(node, "Facehair", t->Colors.Facehair);
|
||||
AddColorPair(node, "Hat", t->Colors.Hat);
|
||||
AddColorPair(node, "Glasses", t->Colors.Glasses);
|
||||
AddColorPair(node, "Feet", t->Colors.Feet);
|
||||
json_insert_child(templates, node);
|
||||
}
|
||||
void PlayerTemplatesSave(const PlayerTemplates *pt)
|
||||
{
|
||||
@@ -234,17 +274,55 @@ bail:
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerTemplateToPlayerData(PlayerData *p, const PlayerTemplate *t)
|
||||
{
|
||||
memset(p->name, 0, sizeof p->name);
|
||||
strcpy(p->name, t->name);
|
||||
p->Char.Class = StrCharacterClass(t->CharClassName);
|
||||
if (p->Char.Class == NULL)
|
||||
{
|
||||
p->Char.Class = StrCharacterClass("Jones");
|
||||
}
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
CFREE(p->Char.HeadParts[hp]);
|
||||
p->Char.HeadParts[hp] = NULL;
|
||||
if (t->HeadParts[hp])
|
||||
{
|
||||
CSTRDUP(p->Char.HeadParts[hp], t->HeadParts[hp]);
|
||||
}
|
||||
}
|
||||
p->Char.Colors = t->Colors;
|
||||
}
|
||||
|
||||
static void PlayerTemplateFromCharacter(PlayerTemplate *t, const Character *c)
|
||||
{
|
||||
CFREE(t->CharClassName);
|
||||
CSTRDUP(t->CharClassName, c->Class->Name);
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
if (c->HeadParts[hp])
|
||||
{
|
||||
CFREE(t->HeadParts[hp]);
|
||||
CSTRDUP(t->HeadParts[hp], c->HeadParts[hp]);
|
||||
}
|
||||
}
|
||||
t->Colors = c->Colors;
|
||||
}
|
||||
|
||||
void PlayerTemplateFromPlayerData(PlayerTemplate *t, const PlayerData *p)
|
||||
{
|
||||
memset(t->name, 0, sizeof t->name);
|
||||
strcpy(t->name, p->name);
|
||||
PlayerTemplateFromCharacter(t, &p->Char);
|
||||
}
|
||||
|
||||
void PlayerTemplateAddCharacter(CArray *classes, const Character *c)
|
||||
{
|
||||
PlayerTemplate t;
|
||||
memset(&t, 0, sizeof t);
|
||||
strncpy(t.name, c->PlayerTemplateName, PLAYER_NAME_MAXLEN - 1);
|
||||
CSTRDUP(t.CharClassName, c->Class->Name);
|
||||
if (c->Hair != NULL)
|
||||
{
|
||||
CSTRDUP(t.Hair, c->Hair);
|
||||
}
|
||||
t.Colors = c->Colors;
|
||||
PlayerTemplateFromCharacter(&t, c);
|
||||
CArrayPushBack(classes, &t);
|
||||
LOG(LM_MAIN, LL_DEBUG, "loaded player template from characters %s (%s)",
|
||||
t.name, t.CharClassName);
|
||||
|
@@ -2,7 +2,7 @@
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
|
||||
Copyright (c) 2013-2014, 2016-2020 Cong Xu
|
||||
Copyright (c) 2013-2014, 2016-2020, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "character.h"
|
||||
#include "character_class.h"
|
||||
#include "player.h"
|
||||
|
||||
#define PLAYER_NAME_MAXLEN 20
|
||||
#define PLAYER_TEMPLATE_FILE "players.cnf"
|
||||
@@ -38,7 +39,7 @@ typedef struct
|
||||
{
|
||||
char name[PLAYER_NAME_MAXLEN];
|
||||
char *CharClassName;
|
||||
char *Hair;
|
||||
char *HeadParts[HEAD_PART_COUNT];
|
||||
CharColors Colors;
|
||||
} PlayerTemplate;
|
||||
|
||||
@@ -56,4 +57,6 @@ void PlayerTemplatesTerminate(PlayerTemplates *pt);
|
||||
|
||||
PlayerTemplate *PlayerTemplateGetById(PlayerTemplates *pt, const int id);
|
||||
void PlayerTemplatesSave(const PlayerTemplates *pt);
|
||||
void PlayerTemplateToPlayerData(PlayerData *p, const PlayerTemplate *t);
|
||||
void PlayerTemplateFromPlayerData(PlayerTemplate *t, const PlayerData *p);
|
||||
void PlayerTemplateAddCharacter(CArray *classes, const Character *c);
|
||||
|
@@ -600,10 +600,26 @@ bool IntsEqual(const void *v1, const void *v2)
|
||||
return *(const int *)v1 == *(const int *)v2;
|
||||
}
|
||||
|
||||
const char *HeadPartStr(const HeadPart hp)
|
||||
{
|
||||
switch (hp)
|
||||
{
|
||||
T2S(HEAD_PART_HAIR, "Hair");
|
||||
T2S(HEAD_PART_FACEHAIR, "Facial Hair");
|
||||
T2S(HEAD_PART_HAT, "Hat");
|
||||
T2S(HEAD_PART_GLASSES, "Glasses");
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
BodyPart StrBodyPart(const char *s)
|
||||
{
|
||||
S2T(BODY_PART_HEAD, "head");
|
||||
S2T(BODY_PART_HAIR, "hair");
|
||||
S2T(BODY_PART_FACEHAIR, "facehair");
|
||||
S2T(BODY_PART_HAT, "hat");
|
||||
S2T(BODY_PART_GLASSES, "glasses");
|
||||
S2T(BODY_PART_BODY, "body");
|
||||
S2T(BODY_PART_LEGS, "legs");
|
||||
S2T(BODY_PART_GUN_R, "gun_r");
|
||||
|
@@ -22,7 +22,7 @@
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
|
||||
Copyright (c) 2013-2017, 2019-2022 Cong Xu
|
||||
Copyright (c) 2013-2017, 2019-2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -214,10 +214,24 @@ bool IntsEqual(const void *v1, const void *v2);
|
||||
((_low) + ((double)rand() / RAND_MAX * ((_high) - (_low))))
|
||||
#define RAND_BOOL() (RAND_INT(0, 1) == 0)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HEAD_PART_HAIR,
|
||||
HEAD_PART_FACEHAIR,
|
||||
HEAD_PART_HAT,
|
||||
HEAD_PART_GLASSES,
|
||||
HEAD_PART_COUNT
|
||||
} HeadPart; // cranial accessories
|
||||
|
||||
const char *HeadPartStr(const HeadPart hp);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BODY_PART_HEAD,
|
||||
BODY_PART_HAIR,
|
||||
BODY_PART_FACEHAIR,
|
||||
BODY_PART_HAT,
|
||||
BODY_PART_GLASSES,
|
||||
BODY_PART_BODY,
|
||||
BODY_PART_LEGS,
|
||||
BODY_PART_GUN_R,
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (c) 2017-2021 Cong Xu
|
||||
Copyright (c) 2017-2021, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -42,13 +42,13 @@ typedef struct
|
||||
CampaignSetting *Setting;
|
||||
bool *FileChanged;
|
||||
char *CharacterClassNames;
|
||||
char *HairNames;
|
||||
char *HeadPartNames[HEAD_PART_COUNT];
|
||||
char *GunNames;
|
||||
char *PickupNames;
|
||||
CArray texidsChars; // of GLuint[BODY_PART_COUNT]
|
||||
GLuint texidsPreview[BODY_PART_COUNT];
|
||||
CArray texIdsCharClasses; // of GLuint
|
||||
CArray texIdsHairs; // of GLuint
|
||||
CArray texIdsHeadParts[HEAD_PART_COUNT]; // of GLuint
|
||||
CArray texIdsGuns; // of GLuint
|
||||
CArray texIdsPickups; // of GLuint
|
||||
Animation anim;
|
||||
@@ -58,7 +58,23 @@ typedef struct
|
||||
} EditorContext;
|
||||
|
||||
static const char *IndexCharacterClassName(const int i);
|
||||
static const char *IndexHairName(const int i);
|
||||
static const char *IndexHeadPartName(const int i, const HeadPart hp);
|
||||
static const char *IndexHairName(const int i)
|
||||
{
|
||||
return IndexHeadPartName(i, HEAD_PART_HAIR);
|
||||
}
|
||||
static const char *IndexFacehairName(const int i)
|
||||
{
|
||||
return IndexHeadPartName(i, HEAD_PART_FACEHAIR);
|
||||
}
|
||||
static const char *IndexHatName(const int i)
|
||||
{
|
||||
return IndexHeadPartName(i, HEAD_PART_HAT);
|
||||
}
|
||||
static const char *IndexGlassesName(const int i)
|
||||
{
|
||||
return IndexHeadPartName(i, HEAD_PART_GLASSES);
|
||||
}
|
||||
static const char *IndexGunName(const int i);
|
||||
static const char *IndexPickupName(const int i);
|
||||
static const WeaponClass *IndexWeaponClassReal(const int i);
|
||||
@@ -93,8 +109,14 @@ void CharEditor(
|
||||
ec.FileChanged = fileChanged;
|
||||
ec.CharacterClassNames =
|
||||
GetClassNames(NumCharacterClasses(), IndexCharacterClassName);
|
||||
ec.HairNames =
|
||||
GetClassNames(gPicManager.hairstyleNames.size, IndexHairName);
|
||||
const char *(*indexHeadPartFuncs[HEAD_PART_COUNT])(int) = {
|
||||
IndexHairName, IndexFacehairName, IndexHatName, IndexGlassesName
|
||||
};
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
ec.HeadPartNames[hp] =
|
||||
GetClassNames(gPicManager.headPartNames[hp].size, *indexHeadPartFuncs[hp]);
|
||||
}
|
||||
ec.GunNames = GetClassNames(NumGuns(), IndexGunName);
|
||||
ec.PickupNames = GetClassNames(NumPickups(), IndexPickupName);
|
||||
|
||||
@@ -115,11 +137,14 @@ void CharEditor(
|
||||
LoadTexFromPic(*texid, GetHeadPic(c, DIRECTION_DOWN, false, &cc));
|
||||
CA_FOREACH_END()
|
||||
|
||||
TexArrayInit(&ec.texIdsHairs, gPicManager.hairstyleNames.size);
|
||||
CA_FOREACH(const GLuint, texid, ec.texIdsHairs)
|
||||
const char *hair = IndexHairName(_ca_index);
|
||||
LoadTexFromPic(*texid, GetHairPic(hair, DIRECTION_DOWN, false, &cc));
|
||||
CA_FOREACH_END()
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
TexArrayInit(&ec.texIdsHeadParts[hp], gPicManager.headPartNames[hp].size);
|
||||
CA_FOREACH(const GLuint, texid, ec.texIdsHeadParts[hp])
|
||||
const char *name = IndexHeadPartName(_ca_index, hp);
|
||||
LoadTexFromPic(*texid, GetHeadPartPic(name, hp, DIRECTION_DOWN, false, &cc));
|
||||
CA_FOREACH_END()
|
||||
}
|
||||
|
||||
TexArrayInit(&ec.texIdsGuns, NumGuns());
|
||||
CA_FOREACH(const GLuint, texid, ec.texIdsGuns)
|
||||
@@ -144,22 +169,27 @@ void CharEditor(
|
||||
NKWindow(cfg);
|
||||
|
||||
CFREE(ec.CharacterClassNames);
|
||||
CFREE(ec.HairNames);
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
CFREE(ec.HeadPartNames[hp]);
|
||||
}
|
||||
CFREE(ec.GunNames);
|
||||
CFREE(ec.PickupNames);
|
||||
glDeleteTextures(
|
||||
(GLsizei)(BODY_PART_COUNT * ec.texidsChars.size), ec.texidsChars.data);
|
||||
CArrayTerminate(&ec.texidsChars);
|
||||
glDeleteTextures(BODY_PART_COUNT, ec.texidsPreview);
|
||||
glDeleteTextures(
|
||||
(GLsizei)ec.texIdsCharClasses.size, ec.texIdsCharClasses.data);
|
||||
TexArrayTerminate(&ec.texIdsCharClasses);
|
||||
glDeleteTextures((GLsizei)ec.texIdsHairs.size, ec.texIdsHairs.data);
|
||||
TexArrayTerminate(&ec.texIdsHairs);
|
||||
glDeleteTextures((GLsizei)ec.texIdsGuns.size, ec.texIdsGuns.data);
|
||||
TexArrayTerminate(&ec.texIdsGuns);
|
||||
glDeleteTextures((GLsizei)ec.texIdsPickups.size, ec.texIdsPickups.data);
|
||||
TexArrayTerminate(&ec.texIdsPickups);
|
||||
#define DELTEX(_tx) \
|
||||
glDeleteTextures( \
|
||||
(GLsizei)(_tx).size, (_tx).data); \
|
||||
TexArrayTerminate(&(_tx));
|
||||
DELTEX(ec.texIdsCharClasses);
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
DELTEX(ec.texIdsHeadParts[hp]);
|
||||
}
|
||||
DELTEX(ec.texIdsGuns);
|
||||
DELTEX(ec.texIdsPickups);
|
||||
}
|
||||
|
||||
static const char *IndexCharacterClassName(const int i)
|
||||
@@ -167,9 +197,9 @@ static const char *IndexCharacterClassName(const int i)
|
||||
const CharacterClass *c = IndexCharacterClass(i);
|
||||
return c->Name;
|
||||
}
|
||||
static const char *IndexHairName(const int i)
|
||||
static const char *IndexHeadPartName(const int i, const HeadPart hp)
|
||||
{
|
||||
return *(char **)CArrayGet(&gPicManager.hairstyleNames, i);
|
||||
return *(char **)CArrayGet(&gPicManager.headPartNames[hp], i);
|
||||
}
|
||||
static int NumCharacterClasses(void)
|
||||
{
|
||||
@@ -333,7 +363,7 @@ static int DrawClassSelection(
|
||||
struct nk_context *ctx, EditorContext *ec, const char *label,
|
||||
const GLuint *texids, const char *items, const int selected,
|
||||
const size_t len);
|
||||
static int HairIndex(const char *hair);
|
||||
static int HeadPartIndex(const char *name, const HeadPart hp);
|
||||
static void DrawFlag(
|
||||
struct nk_context *ctx, EditorContext *ec, const char *label,
|
||||
const int flag, const char *tooltip);
|
||||
@@ -499,32 +529,33 @@ static bool Draw(SDL_Window *win, struct nk_context *ctx, void *data)
|
||||
NumCharacterClasses());
|
||||
ec->Char->Class = IndexCharacterClass(selectedClass);
|
||||
|
||||
nk_layout_row_dynamic(ctx, ROW_HEIGHT, 1);
|
||||
int hasHair = ec->Char->Hair != NULL;
|
||||
nk_checkbox_label(ctx, "Has Hair", &hasHair);
|
||||
|
||||
if (hasHair)
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
nk_layout_row(ctx, NK_DYNAMIC, ROW_HEIGHT, 2, colRatios);
|
||||
const int currentHair = (int)HairIndex(ec->Char->Hair);
|
||||
int selectedHair = DrawClassSelection(
|
||||
ctx, ec, "Hair:", ec->texIdsHairs.data, ec->HairNames,
|
||||
currentHair, gPicManager.hairstyleNames.size);
|
||||
if (selectedHair == -1)
|
||||
nk_layout_row_dynamic(ctx, ROW_HEIGHT, 1);
|
||||
int hasStyle = ec->Char->HeadParts[hp] != NULL;
|
||||
char buf[256];
|
||||
sprintf(buf, "Has %s", HeadPartStr(hp));
|
||||
nk_checkbox_label(ctx, buf, &hasStyle);
|
||||
if (hasStyle)
|
||||
{
|
||||
selectedHair = 0;
|
||||
nk_layout_row(ctx, NK_DYNAMIC, ROW_HEIGHT, 2, colRatios);
|
||||
const int current = HeadPartIndex(ec->Char->HeadParts[hp], hp);
|
||||
sprintf(buf, "%s:", HeadPartStr(hp));
|
||||
int selected = DrawClassSelection(ctx, ec, buf, ec->texIdsHeadParts[hp].data, ec->HeadPartNames[hp], current, gPicManager.headPartNames[hp].size);
|
||||
if (selected == -1)
|
||||
{
|
||||
selected = 0;
|
||||
}
|
||||
if (current != selected)
|
||||
{
|
||||
CharacterSetHeadPart(ec->Char, hp, IndexHeadPartName(selected, hp));
|
||||
}
|
||||
}
|
||||
if (currentHair != selectedHair)
|
||||
else
|
||||
{
|
||||
CFREE(ec->Char->Hair);
|
||||
CSTRDUP(ec->Char->Hair, IndexHairName(selectedHair));
|
||||
CharacterSetHeadPart(ec->Char, hp, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CFREE(ec->Char->Hair);
|
||||
ec->Char->Hair = NULL;
|
||||
}
|
||||
|
||||
// Character colours
|
||||
nk_layout_row(ctx, NK_DYNAMIC, ROW_HEIGHT, 2, colRatios);
|
||||
@@ -536,6 +567,18 @@ static bool Draw(SDL_Window *win, struct nk_context *ctx, void *data)
|
||||
{
|
||||
*ec->FileChanged = true;
|
||||
}
|
||||
if (ColorPicker(ctx, ROW_HEIGHT, "Facial Hair:", &ec->Char->Colors.Facehair))
|
||||
{
|
||||
*ec->FileChanged = true;
|
||||
}
|
||||
if (ColorPicker(ctx, ROW_HEIGHT, "Hat:", &ec->Char->Colors.Hat))
|
||||
{
|
||||
*ec->FileChanged = true;
|
||||
}
|
||||
if (ColorPicker(ctx, ROW_HEIGHT, "Glasses:", &ec->Char->Colors.Glasses))
|
||||
{
|
||||
*ec->FileChanged = true;
|
||||
}
|
||||
if (ColorPicker(ctx, ROW_HEIGHT, "Arms:", &ec->Char->Colors.Arms))
|
||||
{
|
||||
*ec->FileChanged = true;
|
||||
@@ -691,9 +734,10 @@ static void AddCharacter(EditorContext *ec, const int cloneIdx)
|
||||
{
|
||||
CSTRDUP(ec->Char->PlayerTemplateName, clone->PlayerTemplateName);
|
||||
}
|
||||
if (clone->Hair)
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
CSTRDUP(ec->Char->Hair, clone->Hair);
|
||||
ec->Char->HeadParts[hp] = NULL;
|
||||
CharacterSetHeadPart(ec->Char, hp, clone->HeadParts[hp]);
|
||||
}
|
||||
CMALLOC(ec->Char->bot, sizeof *ec->Char->bot);
|
||||
memcpy(ec->Char->bot, clone->bot, sizeof *ec->Char->bot);
|
||||
@@ -708,6 +752,9 @@ static void AddCharacter(EditorContext *ec, const int cloneIdx)
|
||||
ec->Char->Colors.Legs = colorDarkGray;
|
||||
ec->Char->Colors.Hair = colorBlack;
|
||||
ec->Char->Colors.Feet = colorDarkGray;
|
||||
ec->Char->Colors.Facehair = colorDarkGray;
|
||||
ec->Char->Colors.Hat = colorDarkGray;
|
||||
ec->Char->Colors.Glasses = colorDarkGray;
|
||||
ec->Char->speed = 1;
|
||||
ec->Char->Gun = StrWeaponClass("Machine gun");
|
||||
ec->Char->maxHealth = 40;
|
||||
@@ -788,14 +835,14 @@ static int DrawClassSelection(
|
||||
return selectedNew;
|
||||
}
|
||||
|
||||
static int HairIndex(const char *hair)
|
||||
static int HeadPartIndex(const char *name, const HeadPart hp)
|
||||
{
|
||||
if (hair == NULL)
|
||||
if (name == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
CA_FOREACH(const char *, hairstyleName, gPicManager.hairstyleNames)
|
||||
if (strcmp(*hairstyleName, hair) == 0)
|
||||
CA_FOREACH(const char *, hpName, gPicManager.headPartNames[hp])
|
||||
if (strcmp(*hpName, name) == 0)
|
||||
{
|
||||
return _ca_index;
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
|
||||
Copyright (c) 2013-2016, 2018-2021 Cong Xu
|
||||
Copyright (c) 2013-2016, 2018-2021, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -211,7 +211,7 @@ static int HandleInputNameMenu(int cmd, void *data)
|
||||
}
|
||||
|
||||
static void PostInputRotatePlayer(menu_t *menu, int cmd, void *data);
|
||||
static void CheckReenableHairHatMenu(menu_t *menu, void *data);
|
||||
static void CheckReenableHeadPartMenu(menu_t *menu, void *data);
|
||||
|
||||
static void PostInputFaceMenu(menu_t *menu, int cmd, void *data);
|
||||
static menu_t *CreateFaceMenu(MenuDisplayPlayerData *data)
|
||||
@@ -246,32 +246,34 @@ static void PostInputFaceMenu(menu_t *menu, int cmd, void *data)
|
||||
PostInputRotatePlayer(menu, cmd, data);
|
||||
}
|
||||
|
||||
static void PostInputHairMenu(menu_t *menu, int cmd, void *data);
|
||||
static menu_t *CreateHairMenu(MenuDisplayPlayerData *data)
|
||||
static void PostInputHeadPartMenu(menu_t *menu, int cmd, void *data);
|
||||
static menu_t *CreateHeadPartMenu(PlayerSelectMenuData *data, const HeadPart hp)
|
||||
{
|
||||
menu_t *menu = MenuCreateNormal("Hair/hat", "", MENU_TYPE_NORMAL, 0);
|
||||
menu_t *menu = MenuCreateNormal(HeadPartStr(hp), "", MENU_TYPE_NORMAL, 0);
|
||||
menu->u.normal.maxItems = 11;
|
||||
MenuAddSubmenu(menu, MenuCreateBack("(None)"));
|
||||
CA_FOREACH(const char *, h, gPicManager.hairstyleNames)
|
||||
CA_FOREACH(const char *, h, gPicManager.headPartNames[hp])
|
||||
MenuAddSubmenu(menu, MenuCreateBack(*h));
|
||||
CA_FOREACH_END()
|
||||
MenuSetPostInputFunc(menu, PostInputHairMenu, data);
|
||||
HeadPartMenuData *hpmd = &data->headPartData[hp];
|
||||
hpmd->PlayerUID = data->display.PlayerUID;
|
||||
hpmd->HP = hp;
|
||||
MenuSetPostInputFunc(menu, PostInputHeadPartMenu, hpmd);
|
||||
return menu;
|
||||
}
|
||||
static void PostInputHairMenu(menu_t *menu, int cmd, void *data)
|
||||
static void PostInputHeadPartMenu(menu_t *menu, int cmd, void *data)
|
||||
{
|
||||
const MenuDisplayPlayerData *d = data;
|
||||
const HeadPartMenuData *d = data;
|
||||
// Change player hairstyle based on current menu selection
|
||||
PlayerData *p = PlayerDataGetByUID(d->PlayerUID);
|
||||
Character *c = &p->Char;
|
||||
CFREE(c->Hair);
|
||||
c->Hair = NULL;
|
||||
const char *hpName = NULL;
|
||||
if (menu->u.normal.index > 0)
|
||||
{
|
||||
const char **hair =
|
||||
CArrayGet(&gPicManager.hairstyleNames, menu->u.normal.index - 1);
|
||||
CSTRDUP(c->Hair, *hair);
|
||||
hpName =
|
||||
*(const char **)CArrayGet(&gPicManager.headPartNames[d->HP], menu->u.normal.index - 1);
|
||||
}
|
||||
CharacterSetHeadPart(c, d->HP, hpName);
|
||||
PostInputRotatePlayer(menu, cmd, data);
|
||||
}
|
||||
|
||||
@@ -433,20 +435,7 @@ static void PostInputLoadTemplate(menu_t *menu, int cmd, void *data)
|
||||
PlayerData *p = PlayerDataGetByUID(d->display.PlayerUID);
|
||||
const PlayerTemplate *t =
|
||||
PlayerTemplateGetById(&gPlayerTemplates, menu->u.normal.index);
|
||||
memset(p->name, 0, sizeof p->name);
|
||||
strcpy(p->name, t->name);
|
||||
p->Char.Class = StrCharacterClass(t->CharClassName);
|
||||
if (p->Char.Class == NULL)
|
||||
{
|
||||
p->Char.Class = StrCharacterClass("Jones");
|
||||
}
|
||||
CFREE(p->Char.Hair);
|
||||
p->Char.Hair = NULL;
|
||||
if (t->Hair)
|
||||
{
|
||||
CSTRDUP(p->Char.Hair, t->Hair);
|
||||
}
|
||||
p->Char.Colors = t->Colors;
|
||||
PlayerTemplateToPlayerData(p, t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,16 +487,7 @@ static void PostInputSaveTemplate(menu_t *menu, int cmd, void *data)
|
||||
t = CArrayGet(
|
||||
&gPlayerTemplates.Classes, gPlayerTemplates.Classes.size - 1);
|
||||
}
|
||||
memset(t->name, 0, sizeof t->name);
|
||||
strcpy(t->name, p->name);
|
||||
CFREE(t->CharClassName);
|
||||
CSTRDUP(t->CharClassName, p->Char.Class->Name);
|
||||
if (p->Char.Hair)
|
||||
{
|
||||
CFREE(t->Hair);
|
||||
CSTRDUP(t->Hair, p->Char.Hair);
|
||||
}
|
||||
t->Colors = p->Char.Colors;
|
||||
PlayerTemplateFromPlayerData(t, p);
|
||||
PlayerTemplatesSave(&gPlayerTemplates);
|
||||
}
|
||||
|
||||
@@ -627,7 +607,10 @@ static menu_t *CreateCustomizeMenu(
|
||||
menu_t *menu = MenuCreateNormal(name, "", MENU_TYPE_NORMAL, 0);
|
||||
|
||||
MenuAddSubmenu(menu, CreateFaceMenu(&data->display));
|
||||
MenuAddSubmenu(menu, CreateHairMenu(&data->display));
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
MenuAddSubmenu(menu, CreateHeadPartMenu(data, hp));
|
||||
}
|
||||
|
||||
MenuAddSubmenu(
|
||||
menu, CreateColorMenu(
|
||||
@@ -637,6 +620,18 @@ static menu_t *CreateCustomizeMenu(
|
||||
menu, CreateColorMenu(
|
||||
"Hair Color", &data->hairData, data->ms, CHAR_COLOR_HAIR,
|
||||
data->display.PlayerUID));
|
||||
MenuAddSubmenu(
|
||||
menu, CreateColorMenu(
|
||||
"Facial Hair Color", &data->facehairData, data->ms, CHAR_COLOR_FACEHAIR,
|
||||
data->display.PlayerUID));
|
||||
MenuAddSubmenu(
|
||||
menu, CreateColorMenu(
|
||||
"Hat Color", &data->hatData, data->ms, CHAR_COLOR_HAT,
|
||||
data->display.PlayerUID));
|
||||
MenuAddSubmenu(
|
||||
menu, CreateColorMenu(
|
||||
"Glasses Color", &data->glassesData, data->ms, CHAR_COLOR_GLASSES,
|
||||
data->display.PlayerUID));
|
||||
MenuAddSubmenu(
|
||||
menu, CreateColorMenu(
|
||||
"Arms Color", &data->armsData, data->ms, CHAR_COLOR_ARMS,
|
||||
@@ -659,7 +654,7 @@ static menu_t *CreateCustomizeMenu(
|
||||
|
||||
MenuSetPostInputFunc(menu, PostInputRotatePlayer, &data->display);
|
||||
MenuSetPostEnterFunc(
|
||||
menu, CheckReenableHairHatMenu, &data->display, false);
|
||||
menu, CheckReenableHeadPartMenu, &data->display, false);
|
||||
|
||||
return menu;
|
||||
}
|
||||
@@ -690,11 +685,20 @@ static void PostInputRotatePlayer(menu_t *menu, int cmd, void *data)
|
||||
SoundPlay(&gSoundDevice, StrSound(buf));
|
||||
}
|
||||
}
|
||||
static void CheckReenableHairHatMenu(menu_t *menu, void *data)
|
||||
static void CheckReenableHeadPartMenu(menu_t *menu, void *data)
|
||||
{
|
||||
menu_t *hairMenu = MenuGetSubmenuByName(menu, "Hair/hat");
|
||||
CASSERT(hairMenu, "cannot find menu");
|
||||
MenuDisplayPlayerData *d = data;
|
||||
const PlayerData *p = PlayerDataGetByUID(d->PlayerUID);
|
||||
hairMenu->isDisabled = !p->Char.Class->HasHair;
|
||||
char buf[256];
|
||||
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
|
||||
{
|
||||
const bool hasPart = p->Char.Class->HasHeadParts[hp];
|
||||
menu_t *submenu = MenuGetSubmenuByName(menu, HeadPartStr(hp));
|
||||
CASSERT(submenu, "cannot find menu");
|
||||
submenu->isDisabled = !hasPart;
|
||||
sprintf(buf, "%s Color", HeadPartStr(hp));
|
||||
submenu = MenuGetSubmenuByName(menu, buf);
|
||||
CASSERT(submenu, "cannot find menu");
|
||||
submenu->isDisabled = !hasPart;
|
||||
}
|
||||
}
|
||||
|
@@ -34,6 +34,11 @@
|
||||
#include "menu_utils.h"
|
||||
#include "namegen.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int PlayerUID;
|
||||
HeadPart HP;
|
||||
} HeadPartMenuData;
|
||||
typedef struct
|
||||
{
|
||||
CharColorType Type;
|
||||
@@ -47,12 +52,16 @@ typedef struct
|
||||
MenuDisplayPlayerData display;
|
||||
const MenuSystem *ms;
|
||||
int nameMenuSelection;
|
||||
HeadPartMenuData headPartData[HEAD_PART_COUNT];
|
||||
ColorMenuData skinData;
|
||||
ColorMenuData hairData;
|
||||
ColorMenuData armsData;
|
||||
ColorMenuData bodyData;
|
||||
ColorMenuData legsData;
|
||||
ColorMenuData feetData;
|
||||
ColorMenuData facehairData;
|
||||
ColorMenuData hatData;
|
||||
ColorMenuData glassesData;
|
||||
const NameGen *nameGenerator;
|
||||
} PlayerSelectMenuData;
|
||||
typedef struct
|
||||
|
@@ -6,6 +6,9 @@ NCampaignDef.Path max_size:4096
|
||||
NPlayerData.Name max_size:20
|
||||
NPlayerData.CharacterClass max_size:128
|
||||
NPlayerData.Hair max_size:128
|
||||
NPlayerData.Facehair max_size:128
|
||||
NPlayerData.Hat max_size:128
|
||||
NPlayerData.Glasses max_size:128
|
||||
NPlayerData.Weapons max_size:128
|
||||
NPlayerData.Weapons max_count:3
|
||||
NPlayerData.Ammo max_count:128
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.4 */
|
||||
/* Generated by nanopb-0.4.8-dev */
|
||||
|
||||
#include "msg.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
@@ -35,6 +35,9 @@ message NCharColors {
|
||||
NColor Legs = 4;
|
||||
NColor Hair = 5;
|
||||
NColor Feet = 6;
|
||||
NColor Facehair = 7;
|
||||
NColor Hat = 8;
|
||||
NColor Glasses = 9;
|
||||
}
|
||||
|
||||
message NPlayerStats {
|
||||
@@ -49,16 +52,19 @@ message NPlayerData {
|
||||
string Name = 1;
|
||||
string CharacterClass = 2;
|
||||
string Hair = 3;
|
||||
NCharColors Colors = 4;
|
||||
repeated string Weapons = 5;
|
||||
uint32 Lives = 6;
|
||||
NPlayerStats Stats = 7;
|
||||
NPlayerStats Totals = 8;
|
||||
uint32 MaxHealth = 9;
|
||||
uint32 LastMission = 10;
|
||||
uint32 UID = 11;
|
||||
repeated NAmmo Ammo = 12;
|
||||
uint32 HP = 13;
|
||||
string Facehair = 4;
|
||||
string Hat = 5;
|
||||
string Glasses = 6;
|
||||
NCharColors Colors = 7;
|
||||
repeated string Weapons = 8;
|
||||
uint32 Lives = 9;
|
||||
NPlayerStats Stats = 10;
|
||||
NPlayerStats Totals = 11;
|
||||
uint32 MaxHealth = 12;
|
||||
uint32 LastMission = 13;
|
||||
uint32 UID = 14;
|
||||
repeated NAmmo Ammo = 15;
|
||||
uint32 HP = 16;
|
||||
}
|
||||
|
||||
message NPlayerRemove {
|
||||
|