forked from CleverRaven/Cataclysm-DDA
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DEVELOPER_FAQ.txt
133 lines (126 loc) · 9.51 KB
/
DEVELOPER_FAQ.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
1.1 Adding an item
1) Edit itype.h. Change the enum item_id and insert a unique identifier for
your new item type. Be sure to put it among similar items.
2) Edit itypedef.cpp. Macros are used for all item types, and they are pretty
self-explanatory. Be ABSOLUTELY sure that you insert the macro at the same
point in the list as you inserted the identifier in item_id!
3) Your item type is now valid, but won't be spawned. If you want it to be
spawned among similar items, edit mapitemsdef.cpp. Find the appropriate
array(s), and insert the identifier for your item (e.g. itm_aspirin). Make
sure it comes in before the NULL at the end of the list.
5) Some items, like tools or food, also take an iuse::function reference.
Edit iuse.h and include the function in the class declaration; then edit
iuse.cpp and define your function. Functions may be shared among different
item types.
6) If you do not want NPCs to carry the item, add it to the list called
mapitems[mi_trader_avoid] in mapitemsdef.cpp.
1.2 Adding a monster
1) Edit mtype.h. Change the enum mon_id and insert a unique identifier for
your new monster type. Be sure to put it among similar monsters.
2) Edit montypedef.cpp. A macro is used for monsters and it is pretty
straightforward (Any of this ring a bell?). Be ABSOLUTELY sure that you
insert the macro at the same point in the list as your inserted the
identifier in mon_id!
3) Your monster type is now valid, but won't be spawned. If you want it to be
spawned among similar monsters, edit mongroupdef.cpp. Find the appropriate
array, and insert the identifier for your monster (e.g, mon_zombie). Make
sure it comes in before the NULL at the end of the list.
4) If you want your monster to drop items, edit monitemsdef.cpp. Make a new
array for your monster type with all the map item groups it may carry, and a
chance value for each.
5) Your monster may have a special attack, a monattack::function reference.
Edit monattack.h and include the function in the class definition; then
edit monattack.cpp and define your function. Functions may be shared among
different monster types. Be aware that the function should contain a
statement that the monster uses to decide whether or not to use the attack,
and if they do, should reset the monster's attack timer.
7) Just like attacks, some monsters may have a special function called when
they die. This works the same as attacks, but the relevent files are
mondeath.h and mondeath.cpp.
1.3 Adding structures to the map
Most "regular" buildings are spawned in cities (large clusters of buildings which are located rather close to each other).
In file omdata.h in the enum oter_id structure define names (code identifiers) for your building.
If you want your building to be displayed at overmap in different orientations, you should add 4 identifiers for each orientation (south, east, west and north correspondingly).
In the same file in structure const oter_t oterlist[num_ter_types]
we should define how these buildings will be displayed, how much they obscure vision and which extras set they have. For example:
{"mil. surplus", '^', c_white, 5, build_extras, false, false},
{"mil. surplus", '>', c_white, 5, build_extras, false, false},
{"mil. surplus", 'v', c_white, 5, build_extras, false, false},
{"mil. surplus", '<', c_white, 5, build_extras, false, false}
Comments at the beginning of this structure are rather useful.
In the file mapgen.cpp find the subroutine called draw_map(...);
there you should find a huge variant operator ("switch")
where you should put your code defining the new building by adding new case-statement.
This should be mentioned that most buildings are built on the square SEEX*2 x SEEY*2 tiles.
If you want your building to be spawned not only in city limits
you should refer to structures in file omdata.h
(starting from the line #define OMSPEC_FREQ 7).
These structures are commented in source code. Add new identifier in enum omspec_id structure before
NUM_OMSPECS and then add a record in const overmap_special overmap_specials[NUM_OMSPECS] array. For example:
{ot_toxic_dump, 0, 5, 15, -1, mcat_null, 0, 0, 0, 0, &omspec_place::wilderness,0}
The comments given in source code to structure struct overmap_special explains the meaning of these constants in the example above.
1.4 Adding/editing armour and how armour protection is calculated
1) Edit armor.json and add your armor item near similar types.
2) The fields are:
"type" : "ARMOR", // this must be ARMOR
"id" : "socks", // the identifier used by the game. Must be one continuous word, use underscores if necessary
"name" : "socks", // the name appearing in the examine box. Can be more than one word separated by spaces
"weight" : 1, // weight of armour
"color" : "blue", // ascii character colour
"covers" : ["FEET"], // where it covers. Possible options are TORSO, HEAD, EYES, MOUTH, ARMS, HANDS, LEGS, FEET
"to_hit" : 0, // bonus if using it as a melee weapon (whatever for?)
"storage" : 0, // how many volume storage slots it adds
"symbol" : "[", // ascii character
"description" : "Socks. Put 'em on your feet.", // description of armour
"price" : 100, // price of armour, used when bartering with NPCs
"material" : ["COTTON", "NULL"], // material types. See materials.json for possible options
"volume" : 1, // volume occupied
"cutting" : 0, // cutting damage caused by using it as a melee weapon
"warmth" : 10, // how much warmth clothing provides
"phase" : "solid", // what phase it is
"enviromental_protection" : 0, // how much environmental protection it affords
"rarity" : 70, // determines how often it spawns
"encumberance" : 0, // base encumbrance (unfitted value)
"bashing" : -5, // bashing damage caused by using it as a melee weapon
"flags" : ["VARSIZE"] // used to indicate clothing type which can be fitted. Leave out the flags field entirely if clothing cannot be fitted
"coverage" : 80, // what percentage of body part
"material_thickness" : 1 // thickness of material, in millimetre units (approximately). Generally ranges between 1 - 5, more unusual armour types go up to 10 or more
3) When the player is hit at a specific body part, armour coverage determines whether the armour is hit, or an uncovered part of the player is hit (roll 1d100 against coverage)
4) If the above roll fails (ie roll value is above coverage), then the armour does not absorb any damage from the blow, neither does it become damaged
5) If the above roll succeeds, the armour is hit, possibly absorbing some damage and possibly getting damaged in the process
6) The above steps are repeated for each layer of armour on the body part
7) Armour protects against bash and cut damage. These are determined by multiplying the armour thickness by the material bash/cut resistance factor respectively, given in materials.json
8) If the armour is made from 2 materials types, then it takes a weighted average of the primary material (66%) and secondary material (33%).
9) Materials resistance factors are given relative to PAPER as a material (this probably needs some fine-tuning for balance).
1.5 Acid resistance
This determines how items react to acid fields. Item acid resistances are a weighted
average of the materials acid resistance (see item::acid_resist).
An item acid resistance of zero means it will get corroded every turn
An item acid resistance above zero means it has a chance of getting corroded every turn
An item acid resistance above 9 means completely acidproof
Acid resistance values are in materials.json, and defined as such:
0 - zero resistance to acid (metals)
1 - partly resistant to acid
2 - very resistant to acid
3 - complete acid resistance
FAQ
Q: What the heck is up with the map objects?
A: The pertinent map objects are submap, mapbuffer, map, and overmap.
The submap contains the actual map data, in SEEXxSEEY chunks.
Vehicles and Spawns are stored in vectors because they're relatively sparse.
Submaps live in the single global mapbuffer, MAPBUFFER.
Map encapsulates the area around the player that is currently active.
It contains an array of MAPSIZE * MAPSIZE submap pointers called grid.
This is a 2D array, but is mapped to a 1D array for (questionable) indexing purposes.
When the player moves from one submap to another, map::shift() is called.
It moves the pointers in grid to keep the player centered.
The leading edge of grid is populated by map::load()
If the submap has been visited before, it's loaded from MAPBUFFER
Otherwise a 2x2 chunk of submaps is generated based on the corresponding overmap square type.
An overmap encapsulates the large-scale structure of a map
Such as location and layout of cities, forests, rivers, roads, etc...
There are an arbitrary number of overmaps
Additional overmaps are generated as the player enters new areas.
FAQ
Q: what is the relation of NPCS/Monsters vs maps. How are they stored, where are they stored? Are they stored?
A: All npcs are now stored in the overmap. Active npcs only contain the currently active npcs. There is a difference between npc active npc coordinates, and overmap coordinates. So these will need to be changed when saving the npcs. Or else the npcs will be saved at the wrong location. And yes they are stored.