version 1.67 | | version 1.68 |
---|
| | |
| | |
/* | | /* |
* static char *rcs_treasure_c = | | * static char *rcs_treasure_c = |
* "$Id: treasure.c,v 1.67 2006/07/02 15:32:34 tchize Exp $"; | | * "$Id: treasure.c,v 1.68 2006/07/21 10:17:29 gros Exp $"; |
*/ | | */ |
| | |
/* | | /* |
| | |
{ | | { |
int was_magic = op->magic, num_enchantments=0, save_item_power; | | 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) |
* objects giving attributes */ | | creator=op; /* safety & to prevent polymorphed objects giving |
| | * attributes |
| | */ |
| | |
/* If we make an artifact, this information will be destroyed */ | | /* If we make an artifact, this information will be destroyed */ |
save_item_power = op->item_power; | | save_item_power = op->item_power; |
op->item_power = 0; | | op->item_power = 0; |
| | |
if (op->randomitems && op->type != SPELL) { | | if (op->randomitems && op->type != SPELL) |
| | { |
create_treasure(op->randomitems, op,flags ,difficulty, 0); | | create_treasure(op->randomitems, op,flags ,difficulty, 0); |
if (!op->inv) LOG(llevDebug,"fix_generated_item: Unable to generate treasure for %s\n", | | if (!op->inv) |
| | LOG(llevDebug, |
| | "fix_generated_item: Unable to generate treasure for %s\n", |
op->name); | | op->name); |
/* So the treasure doesn't get created again */ | | /* So the treasure doesn't get created again */ |
op->randomitems = NULL; | | op->randomitems = NULL; |
} | | } |
| | |
if (difficulty<1) difficulty=1; | | if (difficulty<1) difficulty=1; |
if (!(flags & GT_MINIMAL)) { | | if (!(flags & GT_MINIMAL)) |
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); | | 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); | | num_enchantments = calc_item_power(op, 1); |
if ((!was_magic && !(RANDOM()%CHANCE_FOR_ARTIFACT)) || op->type == HORN || | | if ((!was_magic && !(RANDOM()%CHANCE_FOR_ARTIFACT)) |
difficulty >= 999 ) | | || op->type == HORN || difficulty >= 999 ) |
generate_artifact(op, difficulty); | | generate_artifact(op, difficulty); |
} | | } |
| | |
/* Object was made an artifact. Calculate its item_power rating. | | /* Object was made an artifact. Calculate its item_power rating. |
* the item_power in the object is what the artfiact adds. | | * the item_power in the object is what the artfiact adds. |
*/ | | */ |
if (op->title) { | | if (op->title) |
| | { |
/* if save_item_power is set, then most likely we started with an | | /* 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 | | * 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 | | * but I have seen things like 'strange rings of fire'. So just |
* out the power from the base power plus what this one adds. Note | | * figure out the power from the base power plus what this one adds. |
* that since item_power is not quite linear, this actually ends up | | * Note that since item_power is not quite linear, this actually |
* being somewhat of a bonus | | * ends up being somewhat of a bonus. |
*/ | | */ |
if (save_item_power) { | | if (save_item_power) |
op->item_power = save_item_power + get_power_from_ench(op->item_power); | | op->item_power = save_item_power + |
} else { | | get_power_from_ench(op->item_power); |
op->item_power = get_power_from_ench(op->item_power + num_enchantments); | | else |
} | | op->item_power = get_power_from_ench(op->item_power |
} else if (save_item_power) { | | + num_enchantments); |
/* 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 | | else if (save_item_power) |
* have calculated some value from the base attributes of the archetype. | | { |
| | /* 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; | | op->item_power = save_item_power; |
} | | } |
| | else |
| | { |
| | /* item_power was zero. This is suspicious, as it may be because it |
| | * was never previously calculated. Let's compute a value and see if |
| | * it is non-zero. If it indeed is, then assign it as the new |
| | * item_power value. |
| | * - gros, 21th of July 2006. |
| | */ |
| | op->item_power = calc_item_power(op,0); |
| | save_item_power = op->item_power; /* Just in case it would get used |
| | * again below */ |
| | } |
} | | } |
| | |
/* materialtype modifications. Note we allow this on artifacts. */ | | /* materialtype modifications. Note we allow this on artifacts. */ |
| | |
set_materialname(op, difficulty, NULL); | | set_materialname(op, difficulty, NULL); |
| | |
if (flags & GT_MINIMAL) { | | if (flags & GT_MINIMAL) |
| | { |
if (op->type == POTION) | | if (op->type == POTION) |
/* Handle healing and magic power potions */ | | /* Handle healing and magic power potions */ |
if (op->stats.sp && !op->randomitems) { | | if (op->stats.sp && !op->randomitems) |
| | { |
object *tmp; | | object *tmp; |
| | |
tmp = create_archetype(spell_mapping[op->stats.sp]); | | tmp = create_archetype(spell_mapping[op->stats.sp]); |
insert_ob_in_ob(tmp, op); | | insert_ob_in_ob(tmp, op); |
op->stats.sp=0; | | op->stats.sp=0; |
} | | } |
} | | } |
else if (!op->title) /* Only modify object if not special */ | | else if (!op->title) /* Only modify object if not special */ |
| | { |
switch(op->type) { | | switch(op->type) { |
case WEAPON: | | case WEAPON: |
case ARMOUR: | | case ARMOUR: |
| | |
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); |
if (!QUERY_FLAG(op, FLAG_CURSED)) | | if (!QUERY_FLAG(op, FLAG_CURSED)) |
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; |
| | |
/* Handle healing and magic power potions */ | | /* Handle healing and magic power potions */ |
if (op->stats.sp && !op->randomitems) { | | if (op->stats.sp && !op->randomitems) |
| | { |
object *tmp; | | object *tmp; |
| | |
tmp = create_archetype(spell_mapping[op->stats.sp]); | | tmp = create_archetype(spell_mapping[op->stats.sp]); |
insert_ob_in_ob(tmp, op); | | insert_ob_in_ob(tmp, op); |
op->stats.sp=0; | | op->stats.sp=0; |
} | | } |
| | |
while(!(is_special=special_potion(op)) && !op->inv) { | | while(!(is_special=special_potion(op)) && !op->inv) |
| | { |
generate_artifact(op,difficulty); | | generate_artifact(op,difficulty); |
if(too_many_tries++ > 10) break; | | if(too_many_tries++ > 10) break; |
} | | } |
/* don't want to change value for healing/magic power potions, | | /* don't want to change value for healing/magic power potions, |
* since the value set on those is already correct. | | * since the value set on those is already correct. |
*/ | | */ |
if (op->inv && op->randomitems) { | | if (op->inv && op->randomitems) |
| | { |
/* value multiplier is same as for scrolls */ | | /* value multiplier is same as for scrolls */ |
op->value=(op->value*op->inv->value); | | op->value=(op->value*op->inv->value); |
op->level = op->inv->level/2+ RANDOM()%difficulty + RANDOM()%difficulty; | | op->level = op->inv->level/2+ RANDOM()%difficulty |
} else { | | + RANDOM()%difficulty; |
| | } |
| | else |
| | { |
FREE_AND_COPY(op->name, "potion"); | | FREE_AND_COPY(op->name, "potion"); |
FREE_AND_COPY(op->name_pl, "potions"); | | FREE_AND_COPY(op->name_pl, "potions"); |
} | | } |
| | |
SET_FLAG(op, FLAG_CURSED); | | SET_FLAG(op, FLAG_CURSED); |
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); |
free_object(op); | | free_object(op); |
op=NULL; | | op=NULL; |
break; | | break; |
} | | } |
if(op->arch!=ring_arch&&op->arch!=amulet_arch) /* It's a special artifact!*/ | | 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_ring_bonus(op,QUERY_FLAG(op, FLAG_CURSED)?-DICE2:DICE2); | | set_ring_bonus(op,QUERY_FLAG(op, FLAG_CURSED)?-DICE2:DICE2); |
if(op->type!=RING) /* Amulets have only one ability */ | | if(op->type!=RING) /* Amulets have only one ability */ |
break; | | break; |
if(!(RANDOM()%4)) { | | if(!(RANDOM()%4)) |
| | { |
int d=(RANDOM()%2 || QUERY_FLAG(op, FLAG_CURSED))?-DICE2:DICE2; | | int d=(RANDOM()%2 || QUERY_FLAG(op, FLAG_CURSED))?-DICE2:DICE2; |
if(d>0) | | if(d>0) |
op->value*=3; | | op->value*=3; |
set_ring_bonus(op,d); | | set_ring_bonus(op,d); |
if(!(RANDOM()%4)) { | | if(!(RANDOM()%4)) |
| | { |
int d=(RANDOM()%3 || QUERY_FLAG(op, FLAG_CURSED))?-DICE2:DICE2; | | int d=(RANDOM()%3 || QUERY_FLAG(op, FLAG_CURSED))?-DICE2:DICE2; |
if(d>0) | | if(d>0) |
op->value*=5; | | op->value*=5; |
| | |
* msg for it, and tailor its properties based on the | | * msg for it, and tailor its properties based on the |
* creator and/or map level we found it on. | | * creator and/or map level we found it on. |
*/ | | */ |
if(!op->msg&&RANDOM()%10) { | | if(!op->msg&&RANDOM()%10) |
| | { |
/* set the book level properly */ | | /* set the book level properly */ |
if(creator->level==0 || QUERY_FLAG(creator,FLAG_ALIVE)) { | | if(creator->level==0 || QUERY_FLAG(creator,FLAG_ALIVE)) |
| | { |
if(op->map&&op->map->difficulty) | | if(op->map&&op->map->difficulty) |
op->level=RANDOM()%(op->map->difficulty)+RANDOM()%10+1; | | op->level=RANDOM()%(op->map->difficulty) |
| | +RANDOM()%10+1; |
else | | else |
op->level=RANDOM()%20+1; | | op->level=RANDOM()%20+1; |
} else | | } |
| | else |
op->level=RANDOM()%creator->level; | | op->level=RANDOM()%creator->level; |
| | |
tailor_readable_ob(op,(creator&&creator->stats.sp)?creator->stats.sp:-1); | | tailor_readable_ob(op,(creator&&creator->stats.sp)? |
| | creator->stats.sp:-1); |
/* books w/ info are worth more! */ | | /* books w/ info are worth more! */ |
op->value*=((op->level>10?op->level:(op->level+1)/2)*((strlen(op->msg)/250)+1)); | | op->value*=((op->level>10?op->level:(op->level+1)/2)* |
| | ((strlen(op->msg)/250)+1)); |
/* creator related stuff */ | | /* creator related stuff */ |
| | |
/* for library, chained books. Note that some monsters have no_pick | | /* for library, chained books. Note that some monsters have |
* set - we don't want to set no pick in that case. | | * no_pick set - we don't want to set no pick in that case. |
*/ | | */ |
if(QUERY_FLAG(creator,FLAG_NO_PICK) && | | if(QUERY_FLAG(creator,FLAG_NO_PICK) && |
!QUERY_FLAG(creator, FLAG_MONSTER)) | | !QUERY_FLAG(creator, FLAG_MONSTER)) |
| | |
* the spell, and value calculation is simpler. | | * the spell, and value calculation is simpler. |
*/ | | */ |
if (op->inv->duration_modifier || op->inv->dam_modifier || | | if (op->inv->duration_modifier || op->inv->dam_modifier || |
op->inv->range_modifier) { | | op->inv->range_modifier) |
| | { |
op->level = level_for_item(op, difficulty, 0); | | op->level = level_for_item(op, difficulty, 0); |
op->value= op->value* op->inv->value * (op->level +50)/ | | op->value= op->value* op->inv->value * (op->level +50)/ |
(op->inv->level + 50); | | (op->inv->level + 50); |
} | | } |
else { | | else |
| | { |
op->level = op->inv->level; | | op->level = op->inv->level; |
op->value = op->value * op->inv->value; | | op->value = op->value * op->inv->value; |
} | | } |
| | |
| | |
case ROD: | | case ROD: |
op->level = level_for_item(op, difficulty, 0); | | op->level = level_for_item(op, difficulty, 0); |
/* Add 50 to both level an divisor to keep prices a little more | | /* Add 50 to both level an divisor to keep prices a little |
* reasonable. Otherwise, a high level version of a low level | | * more reasonable. Otherwise, a high level version of a |
* spell can be worth tons a money (eg, level 20 rod, level 2 spell = | | * low level spell can be worth tons a money (eg, level 20 |
* 10 time multiplier). This way, the value are a bit more reasonable. | | * rod, level 2 spell = 10 time multiplier). This way, the |
| | * value are a bit more reasonable. |
*/ | | */ |
op->value= op->value * op->inv->value * (op->level +50) / (op->inv->level + 50); | | op->value= op->value * op->inv->value * (op->level +50) / |
/* maxhp is used to denote how many 'charges' the rod holds before */ | | (op->inv->level + 50); |
| | /* maxhp is used to denote how many 'charges' the rod holds |
| | * before */ |
if (op->stats.maxhp) | | if (op->stats.maxhp) |
op->stats.maxhp *= MAX(op->inv->stats.sp, op->inv->stats.grace); | | op->stats.maxhp *= MAX(op->inv->stats.sp, op->inv->stats.grace); |
else | | else |
| | |
| | |
case SCROLL: | | case SCROLL: |
op->level = level_for_item(op, difficulty, 0); | | op->level = level_for_item(op, difficulty, 0); |
op->value= op->value * op->inv->value * (op->level +50) / (op->inv->level + 50); | | op->value= op->value * op->inv->value * (op->level +50) / |
| | (op->inv->level + 50); |
/* 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; |
op->nrof = op->inv->nrof; | | op->nrof = op->inv->nrof; |
| | |
trap_adjust(op,difficulty); | | trap_adjust(op,difficulty); |
break; | | break; |
} /* switch type */ | | } /* switch type */ |
| | } |
if (flags & GT_STARTEQUIP) { | | if (flags & GT_STARTEQUIP) |
| | { |
if (op->nrof < 2 && op->type != CONTAINER | | if (op->nrof < 2 && op->type != CONTAINER |
&& op->type != MONEY && ! QUERY_FLAG (op, FLAG_IS_THROWN)) | | && op->type != MONEY && ! QUERY_FLAG (op, FLAG_IS_THROWN)) |
SET_FLAG (op, FLAG_STARTEQUIP); | | SET_FLAG (op, FLAG_STARTEQUIP); |