mirror of
https://github.com/cxong/cdogs-sdl.git
synced 2025-07-23 07:23:01 +02:00
@@ -12,5 +12,5 @@
|
||||
"MaxLives": 4,
|
||||
"PlayerHP": 20,
|
||||
"PlayerMaxHP": 50,
|
||||
"Missions": 11
|
||||
"Missions": 10
|
||||
}
|
@@ -1,141 +1,5 @@
|
||||
{
|
||||
"Missions": [{
|
||||
"Title": "",
|
||||
"Description": "",
|
||||
"Type": "Classic",
|
||||
"Width": 48,
|
||||
"Height": 48,
|
||||
"ExitStyle": "hazard",
|
||||
"KeyStyle": "office",
|
||||
"Objectives": [],
|
||||
"Enemies": [3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8],
|
||||
"SpecialChars": [],
|
||||
"MapObjectDensities": [],
|
||||
"EnemyDensity": 20,
|
||||
"Weapons": ["Knife",
|
||||
"Machine gun",
|
||||
"Grenades",
|
||||
"Flamer",
|
||||
"Shotgun",
|
||||
"Powergun",
|
||||
"Shrapnel bombs",
|
||||
"Molotovs",
|
||||
"Sniper rifle",
|
||||
"Prox. mine",
|
||||
"Dynamite",
|
||||
"Chemo bombs",
|
||||
"Petrify gun",
|
||||
"Browny gun",
|
||||
"Confusion bombs",
|
||||
"Chemo gun",
|
||||
"Pulse rifle",
|
||||
"Heatseeker",
|
||||
"Fists",
|
||||
"Swarmer",
|
||||
"Launcher",
|
||||
"Pistol",
|
||||
"Akimbo Pistols",
|
||||
"Chainsaw",
|
||||
"2xChainsaw",
|
||||
"3xChainsaw",
|
||||
"4xChainsaw",
|
||||
"5xChainsaw",
|
||||
"Fists",
|
||||
"MiniGun",
|
||||
"Launcher",
|
||||
"Flamer",
|
||||
"Powergun",
|
||||
"Lazer",
|
||||
"TurboLazer",
|
||||
"Blaster",
|
||||
"MegaGun",
|
||||
"DumbGun",
|
||||
"Gun"],
|
||||
"WeaponPersist": false,
|
||||
"SkipDebrief": false,
|
||||
"TileClasses": {
|
||||
"Wall": {
|
||||
"Name": "wall",
|
||||
"Type": "Wall",
|
||||
"Style": "steel",
|
||||
"Mask": "848484ff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": false,
|
||||
"IsOpaque": true,
|
||||
"Shootable": true,
|
||||
"IsRoom": false,
|
||||
"DamageBullet": ""
|
||||
},
|
||||
"Floor": {
|
||||
"Name": "tile",
|
||||
"Type": "Floor",
|
||||
"Style": "recessed",
|
||||
"Mask": "484848ff",
|
||||
"MaskAlt": "008400ff",
|
||||
"CanWalk": true,
|
||||
"IsOpaque": false,
|
||||
"Shootable": false,
|
||||
"IsRoom": false,
|
||||
"DamageBullet": ""
|
||||
},
|
||||
"Room": {
|
||||
"Name": "tile",
|
||||
"Type": "Floor",
|
||||
"Style": "recessed",
|
||||
"Mask": "707070ff",
|
||||
"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": 11,
|
||||
"WallLength": 14,
|
||||
"CorridorWidth": 2,
|
||||
"Rooms": {
|
||||
"Count": 3,
|
||||
"Min": 7,
|
||||
"Max": 10,
|
||||
"Edge": false,
|
||||
"Overlap": false,
|
||||
"Walls": 0,
|
||||
"WallLength": 1,
|
||||
"WallPad": 1
|
||||
},
|
||||
"Squares": 0,
|
||||
"ExitEnabled": true,
|
||||
"Doors": {
|
||||
"Enabled": false,
|
||||
"Min": 1,
|
||||
"Max": 1,
|
||||
"RandomPos": false
|
||||
},
|
||||
"Pillars": {
|
||||
"Count": 0,
|
||||
"Min": 1,
|
||||
"Max": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"Title": "Mission 1",
|
||||
"Description": "",
|
||||
"Type": "Classic",
|
||||
@@ -204,6 +68,14 @@
|
||||
"MapObject": "bloodstain1",
|
||||
"Density": 20
|
||||
}],
|
||||
"PickupDensities": [{
|
||||
"Pickup": "gun_Powergun",
|
||||
"Density": 1
|
||||
},
|
||||
{
|
||||
"Pickup": "ammo_Cells",
|
||||
"Density": 1
|
||||
}],
|
||||
"EnemyDensity": 13,
|
||||
"Weapons": ["Fists",
|
||||
"Chainsaw",
|
||||
@@ -339,25 +211,9 @@
|
||||
5],
|
||||
"SpecialChars": [],
|
||||
"MapObjectDensities": [{
|
||||
"MapObject": "crate",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "fan",
|
||||
"Density": 10
|
||||
},
|
||||
{
|
||||
"MapObject": "cabinet_server",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box3_gray",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "blood0",
|
||||
"Density": 10
|
||||
@@ -390,6 +246,14 @@
|
||||
"MapObject": "bloodstain1",
|
||||
"Density": 20
|
||||
}],
|
||||
"PickupDensities": [{
|
||||
"Pickup": "gun_Powergun",
|
||||
"Density": 1
|
||||
},
|
||||
{
|
||||
"Pickup": "ammo_Cells",
|
||||
"Density": 1
|
||||
}],
|
||||
"EnemyDensity": 40,
|
||||
"Weapons": ["Fists",
|
||||
"Chainsaw",
|
||||
@@ -520,25 +384,9 @@
|
||||
5],
|
||||
"SpecialChars": [],
|
||||
"MapObjectDensities": [{
|
||||
"MapObject": "crate",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "fan",
|
||||
"Density": 10
|
||||
},
|
||||
{
|
||||
"MapObject": "cabinet_server",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box3_gray",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "blood0",
|
||||
"Density": 10
|
||||
@@ -571,6 +419,7 @@
|
||||
"MapObject": "bloodstain1",
|
||||
"Density": 20
|
||||
}],
|
||||
"PickupDensities": [],
|
||||
"EnemyDensity": 50,
|
||||
"Weapons": ["Fists",
|
||||
"Chainsaw",
|
||||
@@ -702,25 +551,9 @@
|
||||
6],
|
||||
"SpecialChars": [],
|
||||
"MapObjectDensities": [{
|
||||
"MapObject": "crate",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "fan",
|
||||
"Density": 10
|
||||
},
|
||||
{
|
||||
"MapObject": "cabinet_server",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box3_gray",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "blood0",
|
||||
"Density": 10
|
||||
@@ -753,6 +586,7 @@
|
||||
"MapObject": "bloodstain1",
|
||||
"Density": 20
|
||||
}],
|
||||
"PickupDensities": [],
|
||||
"EnemyDensity": 55,
|
||||
"Weapons": ["Fists",
|
||||
"Chainsaw",
|
||||
@@ -899,25 +733,9 @@
|
||||
5,
|
||||
5],
|
||||
"MapObjectDensities": [{
|
||||
"MapObject": "crate",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "fan",
|
||||
"Density": 10
|
||||
},
|
||||
{
|
||||
"MapObject": "cabinet_server",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box3_gray",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "blood0",
|
||||
"Density": 10
|
||||
@@ -950,6 +768,7 @@
|
||||
"MapObject": "bloodstain1",
|
||||
"Density": 20
|
||||
}],
|
||||
"PickupDensities": [],
|
||||
"EnemyDensity": 13,
|
||||
"Weapons": ["Fists",
|
||||
"Chainsaw",
|
||||
@@ -1089,25 +908,9 @@
|
||||
4,
|
||||
7],
|
||||
"MapObjectDensities": [{
|
||||
"MapObject": "crate",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "fan",
|
||||
"Density": 10
|
||||
},
|
||||
{
|
||||
"MapObject": "cabinet_server",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box3_gray",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "blood0",
|
||||
"Density": 10
|
||||
@@ -1140,6 +943,7 @@
|
||||
"MapObject": "bloodstain1",
|
||||
"Density": 20
|
||||
}],
|
||||
"PickupDensities": [],
|
||||
"EnemyDensity": 13,
|
||||
"Weapons": ["Fists",
|
||||
"Chainsaw",
|
||||
@@ -1283,25 +1087,9 @@
|
||||
7],
|
||||
"SpecialChars": [],
|
||||
"MapObjectDensities": [{
|
||||
"MapObject": "crate",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "fan",
|
||||
"Density": 10
|
||||
},
|
||||
{
|
||||
"MapObject": "cabinet_server",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box3_gray",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "blood0",
|
||||
"Density": 10
|
||||
@@ -1334,6 +1122,7 @@
|
||||
"MapObject": "bloodstain1",
|
||||
"Density": 20
|
||||
}],
|
||||
"PickupDensities": [],
|
||||
"EnemyDensity": 65,
|
||||
"Weapons": ["Fists",
|
||||
"Chainsaw",
|
||||
@@ -1482,25 +1271,9 @@
|
||||
7,
|
||||
8],
|
||||
"MapObjectDensities": [{
|
||||
"MapObject": "crate",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "fan",
|
||||
"Density": 10
|
||||
},
|
||||
{
|
||||
"MapObject": "cabinet_server",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box3_gray",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "blood0",
|
||||
"Density": 10
|
||||
@@ -1533,6 +1306,7 @@
|
||||
"MapObject": "bloodstain1",
|
||||
"Density": 20
|
||||
}],
|
||||
"PickupDensities": [],
|
||||
"EnemyDensity": 13,
|
||||
"Weapons": ["Fists",
|
||||
"Chainsaw",
|
||||
@@ -1663,25 +1437,9 @@
|
||||
7],
|
||||
"SpecialChars": [],
|
||||
"MapObjectDensities": [{
|
||||
"MapObject": "crate",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "fan",
|
||||
"Density": 10
|
||||
},
|
||||
{
|
||||
"MapObject": "cabinet_server",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box3_gray",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "blood0",
|
||||
"Density": 10
|
||||
@@ -1714,6 +1472,7 @@
|
||||
"MapObject": "bloodstain1",
|
||||
"Density": 20
|
||||
}],
|
||||
"PickupDensities": [],
|
||||
"EnemyDensity": 70,
|
||||
"Weapons": ["Fists",
|
||||
"Chainsaw",
|
||||
@@ -1850,25 +1609,9 @@
|
||||
8],
|
||||
"SpecialChars": [],
|
||||
"MapObjectDensities": [{
|
||||
"MapObject": "crate",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "fan",
|
||||
"Density": 10
|
||||
},
|
||||
{
|
||||
"MapObject": "cabinet_server",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "box3_gray",
|
||||
"Density": 20
|
||||
},
|
||||
{
|
||||
"MapObject": "blood0",
|
||||
"Density": 10
|
||||
@@ -1901,6 +1644,7 @@
|
||||
"MapObject": "bloodstain1",
|
||||
"Density": 20
|
||||
}],
|
||||
"PickupDensities": [],
|
||||
"EnemyDensity": 80,
|
||||
"Weapons": ["Fists",
|
||||
"Chainsaw",
|
||||
|
@@ -349,18 +349,24 @@ bool MapTryPlaceDestroyObject(
|
||||
return MapTryPlaceOneObject(mb, pos, mo, ObjectiveToThing(objective), strict);
|
||||
}
|
||||
|
||||
void MapPlacePickup(
|
||||
const PickupClass *p, const struct vec2 pos, const int flags)
|
||||
{
|
||||
GameEvent e = GameEventNew(GAME_EVENT_ADD_PICKUP);
|
||||
strcpy(e.u.AddPickup.PickupClass, p->Name);
|
||||
e.u.AddPickup.ThingFlags = flags;
|
||||
e.u.AddPickup.Pos = Vec2ToNet(pos);
|
||||
GameEventsEnqueue(&gGameEvents, e);
|
||||
}
|
||||
|
||||
void MapPlaceCollectible(
|
||||
const Mission *m, const int objective, const struct vec2 pos)
|
||||
{
|
||||
const Objective *o = CArrayGet(&m->Objectives, objective);
|
||||
GameEvent e = GameEventNew(GAME_EVENT_ADD_PICKUP);
|
||||
// Pick a random pickup out of the available ones
|
||||
const int i = RAND_INT(0, (int)o->u.Pickups.size - 1);
|
||||
const PickupClass *p = *(const PickupClass **)CArrayGet(&o->u.Pickups, i);
|
||||
strcpy(e.u.AddPickup.PickupClass, p->Name);
|
||||
e.u.AddPickup.ThingFlags = ObjectiveToThing(objective);
|
||||
e.u.AddPickup.Pos = Vec2ToNet(pos);
|
||||
GameEventsEnqueue(&gGameEvents, e);
|
||||
MapPlacePickup(p, pos, ObjectiveToThing(objective));
|
||||
}
|
||||
|
||||
struct vec2 MapGenerateFreePosition(Map *map, const struct vec2i size)
|
||||
|
@@ -378,6 +378,17 @@ static json_t *SaveMissions(CArray *a)
|
||||
json_insert_child(modsNode, modNode);
|
||||
}
|
||||
json_insert_pair_into_object(node, "MapObjectDensities", modsNode);
|
||||
json_t *pdsNode = json_new_array();
|
||||
for (int j = 0; j < (int)mission->PickupDensities.size; j++)
|
||||
{
|
||||
const PickupDensity *pd =
|
||||
CArrayGet(&mission->PickupDensities, j);
|
||||
json_t *pdNode = json_new_object();
|
||||
AddStringPair(pdNode, "Pickup", pd->P->Name);
|
||||
AddIntPair(pdNode, "Density", pd->Density);
|
||||
json_insert_child(pdsNode, pdNode);
|
||||
}
|
||||
json_insert_pair_into_object(node, "PickupDensities", pdsNode);
|
||||
|
||||
AddIntPair(node, "EnemyDensity", mission->EnemyDensity);
|
||||
json_insert_pair_into_object(
|
||||
|
@@ -22,7 +22,7 @@
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
|
||||
Copyright (c) 2013-2014, 2017-2022 Cong Xu
|
||||
Copyright (c) 2013-2014, 2017-2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -433,7 +433,6 @@ void MapLoadDynamic(MapBuilder *mb)
|
||||
MapStaticLoadDynamic(mb);
|
||||
}
|
||||
|
||||
// Add map objects
|
||||
CA_FOREACH(const MapObjectDensity, mod, mb->mission->MapObjectDensities)
|
||||
for (int j = 0;
|
||||
j < (mod->Density * mb->Map->Size.x * mb->Map->Size.y) / 1000; j++)
|
||||
@@ -441,6 +440,19 @@ void MapLoadDynamic(MapBuilder *mb)
|
||||
MapTryPlaceOneObject(mb, MapGetRandomTile(mb->Map), mod->M, 0, true);
|
||||
}
|
||||
CA_FOREACH_END()
|
||||
|
||||
CA_FOREACH(const PickupDensity, pd, mb->mission->PickupDensities)
|
||||
for (int j = 0;
|
||||
j < (pd->Density * mb->Map->Size.x * mb->Map->Size.y) / 5000; j++)
|
||||
{
|
||||
const struct vec2 v = MapGetRandomPos(mb->Map);
|
||||
const struct vec2i size = svec2i(COLLECTABLE_W, COLLECTABLE_H);
|
||||
if (!IsCollisionWithWall(v, size))
|
||||
{
|
||||
MapPlacePickup(pd->P, v, 0);
|
||||
}
|
||||
}
|
||||
CA_FOREACH_END()
|
||||
|
||||
if (HasObjectives(gCampaign.Entry.Mode))
|
||||
{
|
||||
|
@@ -22,7 +22,7 @@
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
|
||||
Copyright (c) 2013-2015, 2017-2022 Cong Xu
|
||||
Copyright (c) 2013-2015, 2017-2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -89,6 +89,8 @@ bool MapTryPlaceOneObject(
|
||||
const int extraFlags, const bool isStrictMode);
|
||||
bool MapTryPlaceDestroyObject(
|
||||
MapBuilder *mb, const Mission *m, const int objective, const struct vec2i pos, const bool strict);
|
||||
void MapPlacePickup(
|
||||
const PickupClass *p, const struct vec2 pos, const int flags);
|
||||
// TODO: refactor
|
||||
void MapPlaceCollectible(
|
||||
const Mission *m, const int objective, const struct vec2 pos);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (c) 2014-2017, 2019-2022 Cong Xu
|
||||
Copyright (c) 2014-2017, 2019-2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -258,6 +258,22 @@ void LoadMissions(CArray *missions, json_t *missionsNode, int version)
|
||||
}
|
||||
}
|
||||
}
|
||||
json_t *pdsNode =
|
||||
json_find_first_label(child, "PickupDensities");
|
||||
if (pdsNode && pdsNode->child)
|
||||
{
|
||||
pdsNode = pdsNode->child;
|
||||
for (json_t *pdNode = pdsNode->child; pdNode;
|
||||
pdNode = pdNode->next)
|
||||
{
|
||||
PickupDensity pd;
|
||||
pd.P = StrPickupClass(
|
||||
json_find_first_label(pdNode, "Pickup")
|
||||
->child->text);
|
||||
LoadInt(&pd.Density, pdNode, "Density");
|
||||
CArrayPushBack(&m.PickupDensities, &pd);
|
||||
}
|
||||
}
|
||||
LoadInt(&m.EnemyDensity, child, "EnemyDensity");
|
||||
LoadWeapons(
|
||||
&m.Weapons, json_find_first_label(child, "Weapons")->child);
|
||||
|
@@ -144,6 +144,7 @@ void MissionInit(Mission *m)
|
||||
CArrayInit(&m->Enemies, sizeof(int));
|
||||
CArrayInit(&m->SpecialChars, sizeof(int));
|
||||
CArrayInit(&m->MapObjectDensities, sizeof(MapObjectDensity));
|
||||
CArrayInit(&m->PickupDensities, sizeof(PickupDensity));
|
||||
CArrayInit(&m->Weapons, sizeof(const WeaponClass *));
|
||||
m->Type = MAPTYPE_CLASSIC;
|
||||
m->u.Classic.ExitEnabled = true;
|
||||
@@ -195,6 +196,7 @@ void MissionCopy(Mission *dst, const Mission *src)
|
||||
CArrayCopy(&dst->Enemies, &src->Enemies);
|
||||
CArrayCopy(&dst->SpecialChars, &src->SpecialChars);
|
||||
CArrayCopy(&dst->MapObjectDensities, &src->MapObjectDensities);
|
||||
CArrayCopy(&dst->PickupDensities, &src->PickupDensities);
|
||||
|
||||
dst->EnemyDensity = src->EnemyDensity;
|
||||
CArrayCopy(&dst->Weapons, &src->Weapons);
|
||||
@@ -261,6 +263,7 @@ void MissionTerminate(Mission *m)
|
||||
CArrayTerminate(&m->Enemies);
|
||||
CArrayTerminate(&m->SpecialChars);
|
||||
CArrayTerminate(&m->MapObjectDensities);
|
||||
CArrayTerminate(&m->PickupDensities);
|
||||
CArrayTerminate(&m->Weapons);
|
||||
switch (m->Type)
|
||||
{
|
||||
|
@@ -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
|
||||
@@ -96,6 +96,11 @@ typedef struct
|
||||
int Density;
|
||||
} MapObjectDensity;
|
||||
typedef struct
|
||||
{
|
||||
const PickupClass *P;
|
||||
int Density;
|
||||
} PickupDensity;
|
||||
typedef struct
|
||||
{
|
||||
int Count;
|
||||
int Min;
|
||||
@@ -134,6 +139,7 @@ typedef struct
|
||||
CArray Enemies; // of int (character index)
|
||||
CArray SpecialChars; // of int
|
||||
CArray MapObjectDensities; // of MapObjectDensity
|
||||
CArray PickupDensities; // of PickupDensity
|
||||
|
||||
int EnemyDensity;
|
||||
CArray Weapons; // of WeaponClass *
|
||||
|
@@ -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
|
||||
@@ -310,6 +310,17 @@ static void DeleteItem(Mission *m, int idx)
|
||||
CArrayDelete(&m->MapObjectDensities, idx);
|
||||
}
|
||||
|
||||
static void DeletePickup(Mission *m, int idx)
|
||||
{
|
||||
if (idx >= (int)m->PickupDensities.size)
|
||||
{
|
||||
// Nothing to delete; do nothing
|
||||
return;
|
||||
}
|
||||
idx = CLAMP(idx, 0, (int)m->PickupDensities.size);
|
||||
CArrayDelete(&m->PickupDensities, idx);
|
||||
}
|
||||
|
||||
static void AdjustYC(int *yc)
|
||||
{
|
||||
Mission *mission = CampaignGetCurrentMission(&gCampaign);
|
||||
@@ -361,6 +372,14 @@ static void AdjustXC(int yc, int *xc)
|
||||
*xc, 0, (int)mission->MapObjectDensities.size - 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case YC_PICKUPS:
|
||||
if (mission && mission->PickupDensities.size > 0)
|
||||
{
|
||||
*xc = CLAMP_OPPOSITE(
|
||||
*xc, 0, (int)mission->PickupDensities.size - 1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -555,6 +574,10 @@ static void Delete(int xc, int yc)
|
||||
case YC_ITEMS:
|
||||
DeleteItem(mission, xc);
|
||||
break;
|
||||
|
||||
case YC_PICKUPS:
|
||||
DeletePickup(mission, xc);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (yc >= YC_OBJECTIVES)
|
||||
@@ -1100,6 +1123,15 @@ static void InputInsert(int *xc, const int yc, Mission *mission)
|
||||
*xc = (int)(mission->MapObjectDensities.size - 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case YC_PICKUPS: {
|
||||
PickupDensity pd;
|
||||
pd.P = PickupClassGetById(&gPickupClasses, 0);
|
||||
pd.Density = 0;
|
||||
CArrayPushBack(&mission->PickupDensities, &pd);
|
||||
*xc = (int)(mission->PickupDensities.size - 1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (yc >= YC_OBJECTIVES)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (c) 2013-2016, 2019-2021 Cong Xu
|
||||
Copyright (c) 2013-2016, 2019-2021, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -356,6 +356,21 @@ static const char *GetObjectCountStr(UIObject *o, void *v)
|
||||
(int)gMission.missionData->MapObjectDensities.size);
|
||||
return s;
|
||||
}
|
||||
static const char *GetPickupCountStr(UIObject *o, void *v)
|
||||
{
|
||||
static char s[128];
|
||||
UNUSED(o);
|
||||
UNUSED(v);
|
||||
Mission *m = CampaignGetCurrentMission(&gCampaign);
|
||||
if (!m)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
sprintf(
|
||||
s, "Pickups (%d)",
|
||||
(int)gMission.missionData->PickupDensities.size);
|
||||
return s;
|
||||
}
|
||||
typedef struct
|
||||
{
|
||||
Campaign *co;
|
||||
@@ -416,6 +431,22 @@ static void MissionDrawMapItem(
|
||||
svec2i_add(svec2i_add(pos, o->Pos), svec2i_scale_divide(o->Size, 2)),
|
||||
mod, UIObjectIsHighlighted(o));
|
||||
}
|
||||
static void MissionDrawPickup(
|
||||
UIObject *o, GraphicsDevice *g, struct vec2i pos, void *vData)
|
||||
{
|
||||
UNUSED(g);
|
||||
MissionIndexData *data = vData;
|
||||
if (!CampaignGetCurrentMission(data->co))
|
||||
return;
|
||||
const Mission *m = CampaignGetCurrentMission(data->co);
|
||||
if (data->index >= (int)m->PickupDensities.size)
|
||||
return;
|
||||
const PickupDensity *pd =
|
||||
CArrayGet(&m->PickupDensities, data->index);
|
||||
DisplayPickupWithDensity(
|
||||
svec2i_add(svec2i_add(pos, o->Pos), svec2i_scale_divide(o->Size, 2)),
|
||||
pd, UIObjectIsHighlighted(o));
|
||||
}
|
||||
static void DrawStyleArea(
|
||||
struct vec2i pos, const char *name, const Pic *pic, int idx, int count,
|
||||
int isHighlighted)
|
||||
@@ -635,6 +666,7 @@ static void DeactivateBrush(UIObject *o, void *data)
|
||||
}
|
||||
|
||||
static UIObject *CreateMapItemObjs(Campaign *co, int dy);
|
||||
static UIObject *CreatePickupObjs(Campaign *co, int dy);
|
||||
static UIObject *CreateCharacterObjs(Campaign *co, int dy);
|
||||
static UIObject *CreateSpecialCharacterObjs(Campaign *co, int dy);
|
||||
|
||||
@@ -976,6 +1008,18 @@ static UIObject *CreateEditorObjs(Campaign *co, EditorBrush *brush)
|
||||
"Shift+click to change amounts");
|
||||
UIObjectAddChild(o2, CreateMapItemObjs(co, pos.y));
|
||||
UIObjectAddChild(c, o2);
|
||||
pos.y += th;
|
||||
o2 = UIObjectCopy(o);
|
||||
o2->u.LabelFunc = GetPickupCountStr;
|
||||
o2->Data = NULL;
|
||||
o2->Id = YC_PICKUPS;
|
||||
o2->Pos = pos;
|
||||
CSTRDUP(
|
||||
o2->Tooltip,
|
||||
"Use Insert/" KMOD_CMD_NAME "+i, Delete/" KMOD_CMD_NAME "+d and PageUp/PageDown\n"
|
||||
"Shift+click to change amounts");
|
||||
UIObjectAddChild(o2, CreatePickupObjs(co, pos.y));
|
||||
UIObjectAddChild(c, o2);
|
||||
|
||||
UIObjectDestroy(o);
|
||||
|
||||
@@ -1007,7 +1051,7 @@ static UIObject *CreateMapItemObjs(Campaign *co, int dy)
|
||||
for (int i = 0; i < 32; i++) // TODO: no limit to objects
|
||||
{
|
||||
const int x = 10 + i * 20;
|
||||
// Drop-down menu for objective type
|
||||
// Drop-down menu for map object type
|
||||
UIObject *o2 = UIObjectCopy(o);
|
||||
o2->Id2 = i;
|
||||
CMALLOC(o2->Data, sizeof(MissionIndexData));
|
||||
@@ -1105,6 +1149,97 @@ static void DrawMapItem(
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Campaign *C;
|
||||
int Idx;
|
||||
PickupClass *P;
|
||||
} PickupIndexData;
|
||||
static EditorResult MissionChangePickupDensity(void *vData, int d);
|
||||
static bool PickupObjFunc(UIObject *o, PickupClass *p, void *vData);
|
||||
static UIObject *CreatePickupObjs(Campaign *co, int dy)
|
||||
{
|
||||
UIObject *c = UIObjectCreate(UITYPE_NONE, 0, svec2i_zero(), svec2i_zero());
|
||||
c->Flags = UI_ENABLED_WHEN_PARENT_HIGHLIGHTED_ONLY;
|
||||
|
||||
UIObject *o =
|
||||
UIObjectCreate(UITYPE_CUSTOM, 0, svec2i_zero(), svec2i(20, 40));
|
||||
o->u.CustomDrawFunc = MissionDrawPickup;
|
||||
o->ChangeFuncAlt = MissionChangePickupDensity;
|
||||
o->Flags = UI_LEAVE_YC;
|
||||
for (int i = 0; i < 32; i++) // TODO: no limit to pickups
|
||||
{
|
||||
const int x = 10 + i * 20;
|
||||
// Drop-down menu for pickup type
|
||||
UIObject *o2 = UIObjectCopy(o);
|
||||
o2->Id2 = i;
|
||||
CMALLOC(o2->Data, sizeof(MissionIndexData));
|
||||
o2->IsDynamicData = 1;
|
||||
((MissionIndexData *)o2->Data)->co = co;
|
||||
((MissionIndexData *)o2->Data)->index = i;
|
||||
o2->Pos = svec2i(x, Y_ABS - dy);
|
||||
CSTRDUP(
|
||||
o2->Tooltip,
|
||||
"Click: change pickup; Shift+Click: change density");
|
||||
UIObjectAddChild(
|
||||
o2, CreateAddPickupObjs(
|
||||
svec2i(o2->Size.x, o2->Size.y / 2), PickupObjFunc,
|
||||
o2->Data, sizeof(PickupIndexData), false));
|
||||
UIObjectAddChild(c, o2);
|
||||
}
|
||||
|
||||
UIObjectDestroy(o);
|
||||
return c;
|
||||
}
|
||||
static EditorResult MissionChangePickupDensity(void *vData, int d)
|
||||
{
|
||||
MissionIndexData *data = vData;
|
||||
Mission *m = CampaignGetCurrentMission(data->co);
|
||||
if (data->index >= (int)m->PickupDensities.size)
|
||||
{
|
||||
return EDITOR_RESULT_NONE;
|
||||
}
|
||||
PickupDensity *pd = CArrayGet(&m->PickupDensities, data->index);
|
||||
pd->Density = CLAMP(pd->Density + d, 0, 512);
|
||||
return EDITOR_RESULT_CHANGED;
|
||||
}
|
||||
static EditorResult MissionSetPickup(void *vData, int d);
|
||||
static void DrawPickup(
|
||||
UIObject *o, GraphicsDevice *g, struct vec2i pos, void *vData);
|
||||
static bool PickupObjFunc(UIObject *o, PickupClass *p, void *vData)
|
||||
{
|
||||
o->ChangeFunc = MissionSetPickup;
|
||||
o->u.CustomDrawFunc = DrawPickup;
|
||||
MissionIndexData *data = vData;
|
||||
((PickupIndexData *)o->Data)->C = data->co;
|
||||
((PickupIndexData *)o->Data)->Idx = data->index;
|
||||
((PickupIndexData *)o->Data)->P = p;
|
||||
o->Tooltip = MakePickupTooltip(p);
|
||||
return true;
|
||||
}
|
||||
static EditorResult MissionSetPickup(void *vData, int d)
|
||||
{
|
||||
UNUSED(d);
|
||||
PickupIndexData *data = vData;
|
||||
Mission *m = CampaignGetCurrentMission(data->C);
|
||||
if (data->Idx >= (int)m->PickupDensities.size)
|
||||
{
|
||||
return EDITOR_RESULT_NONE;
|
||||
}
|
||||
PickupDensity *pd = CArrayGet(&m->PickupDensities, data->Idx);
|
||||
pd->P = data->P;
|
||||
return EDITOR_RESULT_CHANGED;
|
||||
}
|
||||
static void DrawPickup(
|
||||
UIObject *o, GraphicsDevice *g, struct vec2i pos, void *vData)
|
||||
{
|
||||
UNUSED(g);
|
||||
const PickupIndexData *data = vData;
|
||||
DisplayPickup(
|
||||
svec2i_add(svec2i_add(pos, o->Pos), svec2i_scale_divide(o->Size, 2)),
|
||||
data->P);
|
||||
}
|
||||
|
||||
static UIObject *CreateCharacterObjs(Campaign *co, int dy)
|
||||
{
|
||||
UIObject *c;
|
||||
|
@@ -22,7 +22,7 @@
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
|
||||
Copyright (c) 2013-2014, 2021 Cong Xu
|
||||
Copyright (c) 2013-2014, 2021, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -60,7 +60,8 @@
|
||||
#define YC_MISSIONLOOKS 4
|
||||
#define YC_CHARACTERS 6
|
||||
#define YC_SPECIALS 7
|
||||
#define YC_ITEMS 9
|
||||
#define YC_ITEMS 8
|
||||
#define YC_PICKUPS 9
|
||||
#define YC_OBJECTIVES 10
|
||||
|
||||
#define XC_MISSIONTITLE 0
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (c) 2014, 2016-2017, 2019-2021 Cong Xu
|
||||
Copyright (c) 2014, 2016-2017, 2019-2021, 2023 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -58,6 +58,28 @@ void DisplayMapItemWithDensity(
|
||||
FontStr(s, svec2i_add(pos, svec2i(-8, 5)));
|
||||
}
|
||||
|
||||
void DisplayPickup(const struct vec2i pos, const PickupClass *p)
|
||||
{
|
||||
const Pic *pic = CPicGetPic(&p->Pic, 0);
|
||||
PicRender(
|
||||
pic, gGraphicsDevice.gameWindow.renderer, svec2i_subtract(pos, svec2i_scale_divide(pic->size, 2)),
|
||||
colorWhite, 0, svec2_one(), SDL_FLIP_NONE, Rect2iZero());
|
||||
}
|
||||
|
||||
void DisplayPickupWithDensity(
|
||||
const struct vec2i pos, const PickupDensity *pd,
|
||||
const bool isHighlighted)
|
||||
{
|
||||
DisplayPickup(pos, pd->P);
|
||||
if (isHighlighted)
|
||||
{
|
||||
FontCh('>', svec2i_add(pos, svec2i(-8, -4)));
|
||||
}
|
||||
char s[10];
|
||||
sprintf(s, "%d", pd->Density);
|
||||
FontStr(s, svec2i_add(pos, svec2i(-8, 5)));
|
||||
}
|
||||
|
||||
void DrawKey(UIObject *o, GraphicsDevice *g, struct vec2i pos, void *vData)
|
||||
{
|
||||
const IndexedEditorBrush *data = vData;
|
||||
@@ -367,6 +389,178 @@ static int CountAddMapItemSubObjs(const UIObject *o)
|
||||
return count;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool (*ObjFunc)(UIObject *, PickupClass *, void *);
|
||||
void *Data;
|
||||
// Data size required for pickup change checking
|
||||
size_t DataSize;
|
||||
struct vec2i GridItemSize;
|
||||
struct vec2i GridSize;
|
||||
struct vec2i PageOffset;
|
||||
} CreateAddPickupObjsImplData;
|
||||
static UIObject *CreateAddPickupObjsImpl(
|
||||
struct vec2i pos, CreateAddPickupObjsImplData data);
|
||||
UIObject *CreateAddPickupObjs(
|
||||
const struct vec2i pos, bool (*objFunc)(UIObject *, PickupClass *, void *),
|
||||
void *data, const size_t dataSize, const bool expandDown)
|
||||
{
|
||||
CreateAddPickupObjsImplData d;
|
||||
d.ObjFunc = objFunc;
|
||||
d.Data = data;
|
||||
d.DataSize = dataSize;
|
||||
d.GridItemSize = svec2i(TILE_WIDTH + 4, TILE_HEIGHT * 2 + 4);
|
||||
d.GridSize = svec2i(8, 6);
|
||||
if (expandDown)
|
||||
{
|
||||
d.PageOffset = svec2i(-5, 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
d.PageOffset =
|
||||
svec2i(-5, -d.GridItemSize.y * d.GridSize.y - FontH() - 5);
|
||||
}
|
||||
return CreateAddPickupObjsImpl(pos, d);
|
||||
}
|
||||
static void CreateAddPickupSubObjs(UIObject *c, void *vData);
|
||||
static UIObject *CreateAddPickupObjsImpl(
|
||||
struct vec2i pos, CreateAddPickupObjsImplData data)
|
||||
{
|
||||
UIObject *c = UIObjectCreate(UITYPE_CONTEXT_MENU, 0, pos, svec2i_zero());
|
||||
c->OnFocusFunc = CreateAddPickupSubObjs;
|
||||
c->IsDynamicData = true;
|
||||
CMALLOC(c->Data, sizeof(CreateAddPickupObjsImplData));
|
||||
memcpy(c->Data, &data, sizeof data);
|
||||
|
||||
return c;
|
||||
}
|
||||
static int CountAddPickupSubObjs(const UIObject *o);
|
||||
static void CreateAddPickupSubObjs(UIObject *c, void *vData)
|
||||
{
|
||||
const CreateAddPickupObjsImplData *data = vData;
|
||||
const int pageSize = data->GridSize.x * data->GridSize.y;
|
||||
// Check if we need to recreate the objs
|
||||
// TODO: this is a very heavyweight way to do it
|
||||
int count = 0;
|
||||
bool allChildrenSame = true;
|
||||
for (int i = 0; i < PickupClassesCount(&gPickupClasses); i++)
|
||||
{
|
||||
PickupClass *p = PickupClassGetById(&gPickupClasses, i);
|
||||
UIObject *o2 = UIObjectCreate(
|
||||
UITYPE_CUSTOM, 0, svec2i_zero(), data->GridItemSize);
|
||||
o2->IsDynamicData = true;
|
||||
CCALLOC(o2->Data, data->DataSize);
|
||||
if (!data->ObjFunc(o2, p, data->Data))
|
||||
{
|
||||
UIObjectDestroy(o2);
|
||||
continue;
|
||||
}
|
||||
const int pageIdx = count / pageSize;
|
||||
if (pageIdx >= (int)c->Children.size)
|
||||
{
|
||||
allChildrenSame = false;
|
||||
break;
|
||||
}
|
||||
const UIObject **op = CArrayGet(&c->Children, pageIdx);
|
||||
const UIObject **octx = CArrayGet(&(*op)->Children, 0);
|
||||
const int idx = count % pageSize;
|
||||
if (idx >= (int)(*octx)->Children.size)
|
||||
{
|
||||
allChildrenSame = false;
|
||||
break;
|
||||
}
|
||||
const UIObject **oc = CArrayGet(&(*octx)->Children, idx);
|
||||
if (memcmp(o2->Data, (*oc)->Data, data->DataSize) != 0)
|
||||
{
|
||||
allChildrenSame = false;
|
||||
UIObjectDestroy(o2);
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
UIObjectDestroy(o2);
|
||||
}
|
||||
int cCount = CountAddPickupSubObjs(c);
|
||||
if (cCount == count && allChildrenSame)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Recreate the child UI objects
|
||||
c->Highlighted = NULL;
|
||||
UIObject **objs = c->Children.data;
|
||||
for (int i = 0; i < (int)c->Children.size; i++, objs++)
|
||||
{
|
||||
UIObjectDestroy(*objs);
|
||||
}
|
||||
CArrayClear(&c->Children);
|
||||
|
||||
// Create pagination
|
||||
int pageNum = 1;
|
||||
UIObject *pageLabel = NULL;
|
||||
UIObject *page = NULL;
|
||||
UIObject *o =
|
||||
UIObjectCreate(UITYPE_CUSTOM, 0, svec2i_zero(), data->GridItemSize);
|
||||
const struct vec2i gridStart = svec2i_zero();
|
||||
struct vec2i pos = svec2i_zero();
|
||||
count = 0;
|
||||
for (int i = 0; i < PickupClassesCount(&gPickupClasses); i++)
|
||||
{
|
||||
PickupClass *p = PickupClassGetById(&gPickupClasses, i);
|
||||
UIObject *o2 = UIObjectCopy(o);
|
||||
o2->IsDynamicData = true;
|
||||
CCALLOC(o2->Data, data->DataSize);
|
||||
if (!data->ObjFunc(o2, p, data->Data))
|
||||
{
|
||||
UIObjectDestroy(o2);
|
||||
continue;
|
||||
}
|
||||
o2->Pos = pos;
|
||||
if (count == 0)
|
||||
{
|
||||
pageLabel = UIObjectCreate(
|
||||
UITYPE_LABEL, 0, svec2i((pageNum - 1) * 10, 0),
|
||||
svec2i(10, FontH()));
|
||||
char buf[32];
|
||||
sprintf(buf, "%d", pageNum);
|
||||
UIObjectSetDynamicLabel(pageLabel, buf);
|
||||
page = UIObjectCreate(
|
||||
UITYPE_CONTEXT_MENU, 0,
|
||||
svec2i_add(data->PageOffset, pageLabel->Size), svec2i_zero());
|
||||
UIObjectAddChild(pageLabel, page);
|
||||
pageNum++;
|
||||
}
|
||||
UIObjectAddChild(page, o2);
|
||||
pos.x += o->Size.x;
|
||||
if (((count + 1) % data->GridSize.x) == 0)
|
||||
{
|
||||
pos.x = gridStart.x;
|
||||
pos.y += o->Size.y;
|
||||
}
|
||||
count++;
|
||||
if (count == pageSize)
|
||||
{
|
||||
count = 0;
|
||||
pos = gridStart;
|
||||
UIObjectAddChild(c, pageLabel);
|
||||
}
|
||||
}
|
||||
if (pageLabel != NULL)
|
||||
{
|
||||
UIObjectAddChild(c, pageLabel);
|
||||
}
|
||||
|
||||
UIObjectDestroy(o);
|
||||
}
|
||||
static int CountAddPickupSubObjs(const UIObject *o)
|
||||
{
|
||||
int count = 0;
|
||||
CA_FOREACH(const UIObject *, page, o->Children)
|
||||
const UIObject **ctx = CArrayGet(&(*page)->Children, 0);
|
||||
count += (int)(*ctx)->Children.size;
|
||||
CA_FOREACH_END()
|
||||
return count;
|
||||
}
|
||||
|
||||
char *MakeMapObjectTooltip(const MapObject *mo)
|
||||
{
|
||||
// Add a descriptive tooltip for the map object
|
||||
@@ -427,6 +621,52 @@ void MapObjectGetExplosionGunNames(const MapObject *mo, char *buf, const char *s
|
||||
}
|
||||
}
|
||||
|
||||
char *MakePickupTooltip(const PickupClass *pc)
|
||||
{
|
||||
// Add a descriptive tooltip for the pickup
|
||||
char buf[512];
|
||||
strcpy(buf, pc->Name);
|
||||
// Add effect descriptions
|
||||
CA_FOREACH(const PickupEffect, pe, pc->Effects)
|
||||
char peBuf[128];
|
||||
switch (pe->Type)
|
||||
{
|
||||
case PICKUP_JEWEL:
|
||||
sprintf(peBuf, "\n- Score: %d", pe->u.Score);
|
||||
break;
|
||||
case PICKUP_HEALTH:
|
||||
sprintf(peBuf, "\n- Health: %d", pe->u.Health);
|
||||
break;
|
||||
case PICKUP_AMMO: {
|
||||
const Ammo *a = AmmoGetById(&gAmmo, pe->u.Ammo.Id);
|
||||
sprintf(peBuf, "\n- Ammo: %s %d", a->Name, (int)pe->u.Ammo.Amount);
|
||||
}
|
||||
break;
|
||||
case PICKUP_KEYCARD:
|
||||
sprintf(peBuf, "\n- Key: %s", KeycardStr(pe->u.Keys));
|
||||
break;
|
||||
case PICKUP_GUN: {
|
||||
const WeaponClass *wc = IdWeaponClass(pe->u.GunId);
|
||||
sprintf(peBuf, "\n- Weapon: %s", wc->name);
|
||||
}
|
||||
break;
|
||||
case PICKUP_SHOW_MAP:
|
||||
strcpy(peBuf, "\n- Show map");
|
||||
break;
|
||||
case PICKUP_LIVES:
|
||||
sprintf(peBuf, "\n- Lives: %d", pe->u.Lives);
|
||||
break;
|
||||
default:
|
||||
CASSERT(false, "Unknown pickup type");
|
||||
break;
|
||||
}
|
||||
strcat(buf, peBuf);
|
||||
CA_FOREACH_END()
|
||||
char *tmp;
|
||||
CSTRDUP(tmp, buf);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static EditorResult CloseChange(void *data, int d);
|
||||
void CreateCloseLabel(UIObject *c, const struct vec2i pos)
|
||||
{
|
||||
|
@@ -61,6 +61,10 @@ typedef struct
|
||||
void DisplayMapItem(const struct vec2i pos, const MapObject *mo);
|
||||
void DisplayMapItemWithDensity(
|
||||
const struct vec2i pos, const MapObjectDensity *mod, const bool isHighlighted);
|
||||
void DisplayPickup(const struct vec2i pos, const PickupClass *p);
|
||||
void DisplayPickupWithDensity(
|
||||
const struct vec2i pos, const PickupDensity *pd,
|
||||
const bool isHighlighted);
|
||||
void DrawKey(UIObject *o, GraphicsDevice *g, struct vec2i pos, void *vData);
|
||||
|
||||
void InsertMission(Campaign *co, Mission *mission, int idx);
|
||||
@@ -75,11 +79,15 @@ UIObject *CreateCampaignSeedObj(const struct vec2i pos, Campaign *co);
|
||||
UIObject *CreateAddMapItemObjs(
|
||||
const struct vec2i pos, bool (*objFunc)(UIObject *, MapObject *, void *),
|
||||
void *data, const size_t dataSize, const bool expandDown);
|
||||
UIObject *CreateAddPickupObjs(
|
||||
const struct vec2i pos, bool (*objFunc)(UIObject *, PickupClass *, void *),
|
||||
void *data, const size_t dataSize, const bool expandDown);
|
||||
UIObject *CreateAddPickupSpawnerObjs(
|
||||
const struct vec2i pos, bool (*objFunc)(UIObject *, MapObject *, void *),
|
||||
void *data, const size_t dataSize);
|
||||
|
||||
char *MakeMapObjectTooltip(const MapObject *mo);
|
||||
char *MakePickupTooltip(const PickupClass *p);
|
||||
void MapObjectGetPlacementFlagNames(const MapObject *mo, char *buf, const char *sep);
|
||||
void MapObjectGetExplosionGunNames(const MapObject *mo, char *buf, const char *sep);
|
||||
|
||||
|
@@ -362,7 +362,7 @@ static char *MakeMapObjectTooltipSimple(const MapObject *mo)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static char *MakePickupTooltip(const MapObject *mo);
|
||||
static char *MakePickupSpawnerTooltip(const MapObject *mo);
|
||||
static bool AddPickupSpawnerBrushObjFunc(
|
||||
UIObject *o, MapObject *mo, void *vData)
|
||||
{
|
||||
@@ -376,10 +376,10 @@ static bool AddPickupSpawnerBrushObjFunc(
|
||||
o->OnUnfocusFunc = DeactivateIndexedEditorBrush;
|
||||
((IndexedEditorBrush *)o->Data)->Brush = vData;
|
||||
((IndexedEditorBrush *)o->Data)->u.MapObject = mo;
|
||||
o->Tooltip = MakePickupTooltip(mo);
|
||||
o->Tooltip = MakePickupSpawnerTooltip(mo);
|
||||
return true;
|
||||
}
|
||||
static char *MakePickupTooltip(const MapObject *mo)
|
||||
static char *MakePickupSpawnerTooltip(const MapObject *mo)
|
||||
{
|
||||
char *tmp;
|
||||
CASSERT(mo->u.PickupClass->Name != NULL, "No pickup name");
|
||||
|
Reference in New Issue
Block a user