version 1.27 | | version 1.28 |
---|
| | |
| | |
/* | | /* |
* static char *rcs_treasure_c = | | * static char *rcs_treasure_c = |
* "$Id: treasure.c,v 1.27 2002/06/09 07:59:30 mwedel Exp $"; | | * "$Id: treasure.c,v 1.28 2002/07/15 04:57:12 mwedel Exp $"; |
*/ | | */ |
| | |
/* | | /* |
CrossFire, A Multiplayer game for X-windows | | CrossFire, A Multiplayer game for X-windows |
| | |
Copyright (C) 2000 Mark Wedel | | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
Copyright (C) 1992 Frank Tore Johansen | | Copyright (C) 1992 Frank Tore Johansen |
| | |
This program is free software; you can redistribute it and/or modify | | This program is free software; you can redistribute it and/or modify |
| | |
along with this program; if not, write to the Free Software | | along with this program; if not, write to the Free Software |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| | |
The author can be reached via e-mail to mwedel@scruz.net | | The authors can be reached via e-mail at crossfire-devel@real-time.com |
*/ | | */ |
| | |
#define ALLOWED_COMBINATION | | #define ALLOWED_COMBINATION |
| | |
void fix_generated_item (object *op, object *creator, int difficulty, | | void fix_generated_item (object *op, object *creator, int difficulty, |
int max_magic, int flags) | | int max_magic, int flags) |
{ | | { |
int was_magic = op->magic; | | int was_magic = op->magic, num_enchantments=0, save_item_power; |
| | |
if(!creator||creator->type==op->type) creator=op; /*safety & to prevent polymorphed | | if(!creator||creator->type==op->type) creator=op; /*safety & to prevent polymorphed |
* objects giving attributes */ | | * objects giving attributes */ |
| | |
| | /* If we make an artifact, this information will be destroyed */ |
| | save_item_power = op->item_power; |
| | op->item_power = 0; |
| | |
if (difficulty<1) difficulty=1; | | if (difficulty<1) difficulty=1; |
if (op->arch == crown_arch) { | | if (op->arch == crown_arch) { |
set_magic(difficulty>25?30:difficulty+5, op, max_magic, flags); | | set_magic(difficulty>25?30:difficulty+5, op, max_magic, flags); |
| | num_enchantments = calc_item_power(op, 1); |
generate_artifact(op,difficulty); | | generate_artifact(op,difficulty); |
} else { | | } else { |
if(!op->magic && max_magic) | | if(!op->magic && max_magic) |
set_magic(difficulty,op,max_magic, flags); | | set_magic(difficulty,op,max_magic, flags); |
| | num_enchantments = calc_item_power(op, 1); |
if ((!was_magic && !(RANDOM()%CHANCE_FOR_ARTIFACT)) || op->type == HORN || | | if ((!was_magic && !(RANDOM()%CHANCE_FOR_ARTIFACT)) || op->type == HORN || |
difficulty >= 999 ) | | difficulty >= 999 ) |
generate_artifact(op, difficulty); | | generate_artifact(op, difficulty); |
} | | } |
| | /* Object was made an artifact. Calculate its item_power rating. |
| | * the item_power in the object is what the artfiact adds. |
| | */ |
| | if (op->title) { |
| | /* if save_item_power is set, then most likely we started with an |
| | * artifact and have added new abilities to it - this is rare, but |
| | * but I have seen things like 'strange rings of fire'. So just figure |
| | * out the power from the base power plus what this one adds. Note |
| | * that since item_power is not quite linear, this actually ends up |
| | * being somewhat of a bonus |
| | */ |
| | if (save_item_power) { |
| | op->item_power = save_item_power + get_power_from_ench(op->item_power); |
| | } else { |
| | op->item_power = get_power_from_ench(op->item_power + num_enchantments); |
| | } |
| | } else if (save_item_power) { |
| | /* restore the item_power field to the object if we haven't changed it. |
| | * we don't care about num_enchantments - that will basically just |
| | * have calculated some value from the base attributes of the archetype. |
| | */ |
| | op->item_power = save_item_power; |
| | } |
| | |
if (!op->title) /* Only modify object if not special */ | | if (!op->title) /* Only modify object if not special */ |
switch(op->type) { | | switch(op->type) { |
case WEAPON: | | case WEAPON: |
| | |
if (QUERY_FLAG(op, FLAG_CURSED) && !(RANDOM()%4)) | | if (QUERY_FLAG(op, FLAG_CURSED) && !(RANDOM()%4)) |
set_ring_bonus(op, -DICE2); | | set_ring_bonus(op, -DICE2); |
break; | | break; |
| | |
case BRACERS: | | case BRACERS: |
if(!(RANDOM()%(QUERY_FLAG(op, FLAG_CURSED)?5:20))) { | | if(!(RANDOM()%(QUERY_FLAG(op, FLAG_CURSED)?5:20))) { |
set_ring_bonus(op,QUERY_FLAG(op, FLAG_CURSED)?-DICE2:DICE2); | | set_ring_bonus(op,QUERY_FLAG(op, FLAG_CURSED)?-DICE2:DICE2); |
| | |
op->value*=3; | | op->value*=3; |
} | | } |
break; | | break; |
| | |
case POTION: { | | case POTION: { |
int too_many_tries=0,is_special=0; | | int too_many_tries=0,is_special=0; |
| | |
| | |
} | | } |
break; | | break; |
} | | } |
| | |
case AMULET: | | case AMULET: |
if(op->arch==amulet_arch) | | if(op->arch==amulet_arch) |
op->value*=5; /* Since it's not just decoration */ | | op->value*=5; /* Since it's not just decoration */ |
| | |
case RING: | | case RING: |
if(op->arch==NULL) { | | if(op->arch==NULL) { |
remove_ob(op); | | remove_ob(op); |
| | |
op=NULL; | | op=NULL; |
break; | | break; |
} | | } |
if(op->arch!=ring_arch&&op->arch!=amulet_arch) /* It's a special artefact!*/ | | if(op->arch!=ring_arch&&op->arch!=amulet_arch) /* It's a special artifact!*/ |
break; | | break; |
| | |
if ( ! (flags & GT_ONLY_GOOD) && ! (RANDOM() % 3)) | | if ( ! (flags & GT_ONLY_GOOD) && ! (RANDOM() % 3)) |
SET_FLAG(op, FLAG_CURSED); | | SET_FLAG(op, FLAG_CURSED); |
set_ring_bonus(op,QUERY_FLAG(op, FLAG_CURSED)?-DICE2:DICE2); | | set_ring_bonus(op,QUERY_FLAG(op, FLAG_CURSED)?-DICE2:DICE2); |
| | |
if(GET_ANIM_ID(op)) | | if(GET_ANIM_ID(op)) |
SET_ANIMATION(op, RANDOM()%((int) NUM_ANIMATIONS(op))); | | SET_ANIMATION(op, RANDOM()%((int) NUM_ANIMATIONS(op))); |
break; | | break; |
| | |
case BOOK: | | case BOOK: |
/* Is it an empty book?, if yes lets make a special | | /* Is it an empty book?, if yes lets make a special |
* msg for it, and tailor its properties based on the | | * msg for it, and tailor its properties based on the |
| | |
op->stats.exp = op->value>10000?op->value/5:op->value/10; | | op->stats.exp = op->value>10000?op->value/5:op->value/10; |
} | | } |
break; | | break; |
| | |
case SPELLBOOK: | | case SPELLBOOK: |
if (op->slaying | | if (op->slaying && (op->stats.sp = look_up_spell_name (op->slaying)) >= 0) { |
&& (op->stats.sp = look_up_spell_name (op->slaying)) >= 0) | | |
{ | | |
free_string (op->slaying); | | free_string (op->slaying); |
op->slaying = NULL; | | op->slaying = NULL; |
} | | } |
else if(!strcmp(op->arch->name,"cleric_book")) | | else if(!strcmp(op->arch->name,"cleric_book")) |
do { | | do { |
do | | |
op->stats.sp=RANDOM()%NROFREALSPELLS; | | op->stats.sp=RANDOM()%NROFREALSPELLS; |
while(RANDOM()%10>=spells[op->stats.sp].books); | | } while((RANDOM()%10>=spells[op->stats.sp].books) || !spells[op->stats.sp].cleric); |
} while (!spells[op->stats.sp].cleric); | | else do { |
else | | |
do { | | |
do | | |
op->stats.sp=RANDOM()%NROFREALSPELLS; | | op->stats.sp=RANDOM()%NROFREALSPELLS; |
while(RANDOM()%10>=spells[op->stats.sp].books); | | } while((RANDOM()%10>=spells[op->stats.sp].books) || spells[op->stats.sp].cleric); |
} while (spells[op->stats.sp].cleric); | | |
| | |
op->value=(op->value*spells[op->stats.sp].level)/ | | op->value=(op->value*spells[op->stats.sp].level)/(spells[op->stats.sp].level+4); |
(spells[op->stats.sp].level+4); | | |
change_book(op,-1); | | change_book(op,-1); |
| | |
/* add exp so learning gives xp */ | | /* add exp so learning gives xp */ |
op->level = spells[op->stats.sp].level; | | op->level = spells[op->stats.sp].level; |
op->stats.exp = op->value; | | op->stats.exp = op->value; |
| | |
break; | | break; |
| | |
case WAND: | | case WAND: |
do | | do |
op->stats.sp=RANDOM()%NROFREALSPELLS; | | op->stats.sp=RANDOM()%NROFREALSPELLS; |
while (!spells[op->stats.sp].charges|| | | while (!spells[op->stats.sp].charges|| spells[op->stats.sp].level>DICESPELL); |
spells[op->stats.sp].level>DICESPELL); | | |
if (spells[op->stats.sp].cleric) | | if (spells[op->stats.sp].cleric) { |
{ /* Make the wand into a staff */ | | /* Make the wand into a staff */ |
short i = op->stats.sp; | | short i = op->stats.sp; |
if (staff_arch == NULL) | | if (staff_arch == NULL) |
staff_arch = find_archetype("staff"); | | staff_arch = find_archetype("staff"); |
| | |
op->stats.food=RANDOM()%spells[op->stats.sp].charges+1; | | op->stats.food=RANDOM()%spells[op->stats.sp].charges+1; |
op->level = spells[op->stats.sp].level/2+ RANDOM()%difficulty + RANDOM()%difficulty; | | op->level = spells[op->stats.sp].level/2+ RANDOM()%difficulty + RANDOM()%difficulty; |
if (op->level<1) op->level=1; | | if (op->level<1) op->level=1; |
op->value=(op->value*spells[op->stats.sp].level)/ | | op->value=(op->value*spells[op->stats.sp].level)/ (spells[op->stats.sp].level+4); |
(spells[op->stats.sp].level+4); | | |
break; | | break; |
| | |
case ROD: | | case ROD: |
if (op->stats.maxhp) | | if (op->stats.maxhp) |
op->stats.maxhp += RANDOM()%op->stats.maxhp; | | op->stats.maxhp += RANDOM()%op->stats.maxhp; |
| | |
while (!spells[op->stats.sp].charges|| | | while (!spells[op->stats.sp].charges|| |
spells[op->stats.sp].sp > op->stats.maxhp || | | spells[op->stats.sp].sp > op->stats.maxhp || |
spells[op->stats.sp].level>DICESPELL); | | spells[op->stats.sp].level>DICESPELL); |
| | |
op->level = spells[op->stats.sp].level/2+ RANDOM()%difficulty + RANDOM()%difficulty; | | op->level = spells[op->stats.sp].level/2+ RANDOM()%difficulty + RANDOM()%difficulty; |
op->value=(op->value*op->stats.hp*spells[op->stats.sp].level)/ | | op->value=(op->value*op->stats.hp*spells[op->stats.sp].level)/ |
(spells[op->stats.sp].level+4); | | (spells[op->stats.sp].level+4); |
break; | | break; |
| | |
case SCROLL: | | case SCROLL: |
do | | do |
op->stats.sp=RANDOM()%NROFREALSPELLS; | | op->stats.sp=RANDOM()%NROFREALSPELLS; |
while (!spells[op->stats.sp].scrolls|| | | while (!spells[op->stats.sp].scrolls || spells[op->stats.sp].scroll_chance<=RANDOM()%10); |
spells[op->stats.sp].scroll_chance<=RANDOM()%10); | | |
op->nrof=RANDOM()%spells[op->stats.sp].scrolls+1; | | op->nrof=RANDOM()%spells[op->stats.sp].scrolls+1; |
op->level = spells[op->stats.sp].level/2+ RANDOM()%difficulty + | | op->level = spells[op->stats.sp].level/2+ RANDOM()%difficulty + RANDOM()%difficulty; |
RANDOM()%difficulty; | | |
if (op->level<1) op->level=1; | | if (op->level<1) op->level=1; |
op->value=(op->value*spells[op->stats.sp].level)/ | | op->value=(op->value*spells[op->stats.sp].level)/ (spells[op->stats.sp].level+4); |
(spells[op->stats.sp].level+4); | | |
| | |
/* add exp so reading them properly gives xp */ | | /* add exp so reading them properly gives xp */ |
op->stats.exp = op->value/5; | | op->stats.exp = op->value/5; |
| | |
break; | | break; |
| | |
case RUNE: | | case RUNE: |
(*trap_adjust_func)(op,difficulty); | | (*trap_adjust_func)(op,difficulty); |
break; | | break; |
} | | } /* switch type */ |
| | |
if (op->type == POTION && special_potion(op)) { | | if (op->type == POTION && special_potion(op)) { |
/*if(op->face==blank_face) op->face = potion_face;*/ | | /*if(op->face==blank_face) op->face = potion_face;*/ |
FREE_AND_COPY(op->name, "potion"); | | FREE_AND_COPY(op->name, "potion"); |
| | |
| | |
if ( ! (flags & GT_ENVIRONMENT)) | | if ( ! (flags & GT_ENVIRONMENT)) |
fix_flesh_item (op, creator); | | fix_flesh_item (op, creator); |
| | |
} | | } |
| | |
/* | | /* |
| | |
else | | else |
op->level += change->level; | | op->level += change->level; |
| | |
| | if (change->gen_sp_armour < 0) |
| | op->gen_sp_armour = -(change->gen_sp_armour); |
| | else |
| | op->gen_sp_armour = (op->gen_sp_armour * (change->gen_sp_armour)) / 100; |
| | |
| | op->item_power = change->item_power; |
| | |
for (i=0; i<NROFATTACKS; i++) { | | for (i=0; i<NROFATTACKS; i++) { |
if (change->resist[i]) { | | if (change->resist[i]) { |
| | |
else | | else |
op->last_sp = (signed char) (((int)op->last_sp * (int)change->last_sp) / (int) 100); | | op->last_sp = (signed char) (((int)op->last_sp * (int)change->last_sp) / (int) 100); |
} | | } |
if (change->last_heal) { | | if (change->gen_sp_armour) { |
if (change->last_heal < 0) | | if (change->gen_sp_armour < 0) |
op->last_heal = (-change->last_heal); | | op->gen_sp_armour = (-change->gen_sp_armour); |
else | | else |
op->last_heal = (signed char) (((int)op->last_heal * ((int)change->last_heal)) | | op->gen_sp_armour = (signed char) (((int)op->gen_sp_armour * ((int)change->gen_sp_armour)) |
/ (int)100); | | / (int)100); |
} | | } |
op->value *= change->value; | | op->value *= change->value; |
| | |
char identified = QUERY_FLAG(op, FLAG_IDENTIFIED); | | char identified = QUERY_FLAG(op, FLAG_IDENTIFIED); |
SET_FLAG(op, FLAG_IDENTIFIED); | | SET_FLAG(op, FLAG_IDENTIFIED); |
LOG(llevDebug, "Generated artifact %s %s [%s]\n", | | LOG(llevDebug, "Generated artifact %s %s [%s]\n", |
op->name, op->title, describe_item(op)); | | op->name, op->title, describe_item(op, NULL)); |
if (!identified) | | if (!identified) |
CLEAR_FLAG(op, FLAG_IDENTIFIED); | | CLEAR_FLAG(op, FLAG_IDENTIFIED); |
} | | } |