MCPcopy Create free account
hub / github.com/NetHack/NetHack / mk_artifact

Function mk_artifact

src/artifact.c:171–309  ·  view source on GitHub ↗

Make an artifact. If a specific alignment is specified, then an object of the appropriate alignment is created from scratch, or 0 is returned if none is available. (If at least one aligned artifact has already been given, then unaligned ones also become eligible for this.) If no alignment is given, then 'otmp' is converted into an artifact of matching type, or returned as-is if th

Source from the content-addressed store, hash-verified

169 by sacrificing, or 99 otherwise.
170 */
171struct obj *
172mk_artifact(
173 struct obj *otmp, /* existing object; ignored and disposed of
174 * if alignment specified */
175 aligntyp alignment, /* target alignment, or A_NONE */
176 uchar max_giftvalue, /* cap on generated giftvalue */
177 boolean adjust_spe) /* whether to add spe to situational artifacts */
178{
179 const struct artifact *a;
180 int m, n, altn;
181 boolean by_align = (alignment != A_NONE);
182 short o_typ = (by_align || !otmp) ? 0 : otmp->otyp;
183 boolean unique = !by_align && otmp && objects[o_typ].oc_unique;
184 short eligible[NROFARTIFACTS];
185 xint16 skill_compatibility;
186
187 n = altn = 0; /* no candidates found yet */
188 eligible[0] = 0; /* lint suppression */
189 /* gather eligible artifacts */
190 for (m = 1, a = &artilist[m]; a->otyp; a++, m++) {
191 if (artiexist[m].exists)
192 continue;
193 if ((a->spfx & SPFX_NOGEN) || unique)
194 continue;
195 if (a->gift_value > max_giftvalue && !Role_if(a->role))
196 continue;
197
198 if (!by_align) {
199 /* looking for a particular type of item; not producing a
200 divine gift so we don't care about role's first choice */
201 if (a->otyp == o_typ)
202 eligible[n++] = m;
203 continue; /* move on to next possibility */
204 }
205
206 /* we're looking for an alignment-specific item
207 suitable for hero's role+race */
208 if ((a->alignment == alignment || a->alignment == A_NONE)
209 /* avoid enemies' equipment */
210 && (a->race == NON_PM || !race_hostile(&mons[a->race]))) {
211 /* when a role-specific first choice is available, use it */
212 if (Role_if(a->role)) {
213 /* make this be the only possibility in the list */
214 eligible[0] = m;
215 n = 1;
216 break; /* skip all other candidates */
217 }
218
219 /* check if this is skill-compatible */
220 skill_compatibility = P_SKILLED;
221 if (objects[a->otyp].oc_class == WEAPON_CLASS) {
222 schar skill = objects[a->otyp].oc_skill;
223 if (skill < 0)
224 skill_compatibility = P_MAX_SKILL(-skill);
225 else
226 skill_compatibility = P_MAX_SKILL(skill);
227 }
228

Callers 4

mk_mplayerFunction · 0.85
bestow_artifactFunction · 0.85
mksobj_initFunction · 0.85
mksobjFunction · 0.85

Calls 6

rn2Function · 0.85
mksobjFunction · 0.85
dispose_of_orig_objFunction · 0.85
onameFunction · 0.85
artifact_originFunction · 0.85
permapoisonedFunction · 0.85

Tested by

no test coverage detected