1 | /* |
1 | /* |
2 | * static char *rcsid_apply_c = |
2 | * static char *rcsid_apply_c = |
3 | * "$Id: apply.C,v 1.19 2006/09/03 14:33:46 elmex Exp $"; |
3 | * "$Id: apply.C,v 1.20 2006/09/04 16:46:33 root Exp $"; |
4 | */ |
4 | */ |
5 | /* |
5 | /* |
6 | CrossFire, A Multiplayer game for X-windows |
6 | CrossFire, A Multiplayer game for X-windows |
7 | |
7 | |
8 | Copyright (C) 2001 Mark Wedel & Crossfire Development Team |
8 | Copyright (C) 2001 Mark Wedel & Crossfire Development Team |
… | |
… | |
3441 | * fix_auto_apply goes through the entire map (only the first time |
3441 | * fix_auto_apply goes through the entire map (only the first time |
3442 | * when an original map is loaded) and performs special actions for |
3442 | * when an original map is loaded) and performs special actions for |
3443 | * certain objects (most initialization of chests and creation of |
3443 | * certain objects (most initialization of chests and creation of |
3444 | * treasures and stuff). Calls auto_apply if appropriate. |
3444 | * treasures and stuff). Calls auto_apply if appropriate. |
3445 | */ |
3445 | */ |
3446 | |
3446 | void |
3447 | void fix_auto_apply(mapstruct *m) { |
3447 | fix_auto_apply (mapstruct * m) |
|
|
3448 | { |
3448 | object *tmp,*above=NULL; |
3449 | object *tmp, *above = NULL; |
3449 | int x,y; |
3450 | int x, y; |
3450 | |
3451 | |
3451 | if(m==NULL) return; |
3452 | if (m == NULL) |
|
|
3453 | return; |
3452 | |
3454 | |
3453 | for(x=0;x<MAP_WIDTH(m);x++) |
3455 | for (x = 0; x < MAP_WIDTH (m); x++) |
3454 | for(y=0;y<MAP_HEIGHT(m);y++) |
3456 | for (y = 0; y < MAP_HEIGHT (m); y++) |
3455 | for(tmp=get_map_ob(m,x,y);tmp!=NULL;tmp=above) { |
3457 | for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = above) |
|
|
3458 | { |
3456 | above=tmp->above; |
3459 | above = tmp->above; |
3457 | |
3460 | |
3458 | if (tmp->inv) { |
3461 | if (tmp->inv) |
|
|
3462 | { |
3459 | object *invtmp, *invnext; |
3463 | object *invtmp, *invnext; |
3460 | |
3464 | |
3461 | for (invtmp=tmp->inv; invtmp != NULL; invtmp = invnext) { |
3465 | for (invtmp = tmp->inv; invtmp != NULL; invtmp = invnext) |
|
|
3466 | { |
3462 | invnext = invtmp->below; |
3467 | invnext = invtmp->below; |
3463 | |
3468 | |
3464 | if(QUERY_FLAG(invtmp,FLAG_AUTO_APPLY)) |
3469 | if (QUERY_FLAG (invtmp, FLAG_AUTO_APPLY)) |
3465 | auto_apply(invtmp); |
3470 | auto_apply (invtmp); |
3466 | else if(invtmp->type==TREASURE && HAS_RANDOM_ITEMS(invtmp)) { |
3471 | else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS (invtmp)) |
|
|
3472 | { |
3467 | while ((invtmp->stats.hp--)>0) |
3473 | while ((invtmp->stats.hp--) > 0) |
3468 | create_treasure(invtmp->randomitems, invtmp, 0, |
3474 | create_treasure (invtmp->randomitems, invtmp, 0, m->difficulty, 0); |
3469 | m->difficulty,0); |
3475 | |
3470 | invtmp->randomitems = NULL; |
3476 | invtmp->randomitems = NULL; |
3471 | } |
|
|
3472 | else if (invtmp && invtmp->arch && |
|
|
3473 | invtmp->type!=TREASURE && |
|
|
3474 | invtmp->type != SPELL && |
|
|
3475 | invtmp->type != CLASS && |
|
|
3476 | HAS_RANDOM_ITEMS(invtmp)) { |
|
|
3477 | create_treasure(invtmp->randomitems, invtmp, 0, |
|
|
3478 | m->difficulty,0); |
|
|
3479 | /* Need to clear this so that we never try to create |
|
|
3480 | * treasure again for this object |
|
|
3481 | */ |
|
|
3482 | invtmp->randomitems = NULL; |
|
|
3483 | } |
|
|
3484 | } |
3477 | } |
3485 | /* This is really temporary - the code at the bottom will |
3478 | else if (invtmp && invtmp->arch |
3486 | * also set randomitems to null. The problem is there are bunches |
3479 | && invtmp->type != TREASURE |
3487 | * of maps/players already out there with items that have spells |
3480 | && invtmp->type != SPELL |
3488 | * which haven't had the randomitems set to null yet. |
3481 | && invtmp->type != CLASS |
3489 | * MSW 2004-05-13 |
3482 | && HAS_RANDOM_ITEMS (invtmp)) |
3490 | * |
3483 | { |
3491 | * And if it's a spellbook, it's better to set randomitems to NULL too, |
3484 | create_treasure (invtmp->randomitems, invtmp, 0, |
3492 | * else you get two spells in the book ^_- |
3485 | m->difficulty, 0); |
3493 | * Ryo 2004-08-16 |
3486 | /* Need to clear this so that we never try to create |
|
|
3487 | * treasure again for this object |
3494 | */ |
3488 | */ |
3495 | if (tmp->type == WAND || tmp->type == ROD || tmp->type == SCROLL || |
|
|
3496 | tmp->type == HORN || tmp->type == FIREWALL || tmp->type == POTION || |
|
|
3497 | tmp->type == ALTAR || tmp->type == SPELLBOOK) |
|
|
3498 | tmp->randomitems = NULL; |
|
|
3499 | |
|
|
3500 | } |
|
|
3501 | |
|
|
3502 | if(QUERY_FLAG(tmp,FLAG_AUTO_APPLY)) |
|
|
3503 | auto_apply(tmp); |
|
|
3504 | else if((tmp->type==TREASURE || (tmp->type==CONTAINER))&& HAS_RANDOM_ITEMS(tmp)) { |
|
|
3505 | while ((tmp->stats.hp--)>0) |
|
|
3506 | create_treasure(tmp->randomitems, tmp, 0, |
|
|
3507 | m->difficulty,0); |
|
|
3508 | tmp->randomitems = NULL; |
3489 | invtmp->randomitems = NULL; |
3509 | } |
|
|
3510 | else if(tmp->type==TIMED_GATE) { |
|
|
3511 | object *head = tmp->head != NULL ? tmp->head : tmp; |
|
|
3512 | if (QUERY_FLAG(head, FLAG_IS_LINKED)) { |
|
|
3513 | tmp->speed = 0; |
|
|
3514 | update_ob_speed(tmp); |
|
|
3515 | } |
3490 | } |
3516 | } |
3491 | } |
3517 | /* This function can be called everytime a map is loaded, even when |
3492 | /* This is really temporary - the code at the bottom will |
3518 | * swapping back in. As such, we don't want to create the treasure |
3493 | * also set randomitems to null. The problem is there are bunches |
3519 | * over and ove again, so after we generate the treasure, blank out |
3494 | * of maps/players already out there with items that have spells |
3520 | * randomitems so if it is swapped in again, it won't make anything. |
3495 | * which haven't had the randomitems set to null yet. |
3521 | * This is a problem for the above objects, because they have counters |
3496 | * MSW 2004-05-13 |
3522 | * which say how many times to make the treasure. |
3497 | * |
|
|
3498 | * And if it's a spellbook, it's better to set randomitems to NULL too, |
|
|
3499 | * else you get two spells in the book ^_- |
|
|
3500 | * Ryo 2004-08-16 |
3523 | */ |
3501 | */ |
3524 | else if(tmp && tmp->arch && tmp->type!=PLAYER && tmp->type!=TREASURE && |
3502 | if (tmp->type == WAND || tmp->type == ROD || tmp->type == SCROLL |
3525 | tmp->type != SPELL && tmp->type != PLAYER_CHANGER && tmp->type != CLASS && |
3503 | || tmp->type == HORN || tmp->type == FIREWALL |
3526 | HAS_RANDOM_ITEMS(tmp)) { |
3504 | || tmp->type == POTION || tmp->type == ALTAR |
3527 | create_treasure(tmp->randomitems, tmp, GT_APPLY, |
3505 | || tmp->type == SPELLBOOK) |
3528 | m->difficulty,0); |
|
|
3529 | tmp->randomitems = NULL; |
3506 | tmp->randomitems = NULL; |
|
|
3507 | |
|
|
3508 | } |
|
|
3509 | |
|
|
3510 | if (QUERY_FLAG (tmp, FLAG_AUTO_APPLY)) |
|
|
3511 | auto_apply (tmp); |
|
|
3512 | else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) |
|
|
3513 | && HAS_RANDOM_ITEMS (tmp)) |
|
|
3514 | { |
|
|
3515 | while ((tmp->stats.hp--) > 0) |
|
|
3516 | create_treasure (tmp->randomitems, tmp, 0, m->difficulty, 0); |
|
|
3517 | tmp->randomitems = NULL; |
|
|
3518 | } |
|
|
3519 | else if (tmp->type == TIMED_GATE) |
|
|
3520 | { |
|
|
3521 | object *head = tmp->head != NULL ? tmp->head : tmp; |
|
|
3522 | if (QUERY_FLAG (head, FLAG_IS_LINKED)) |
|
|
3523 | { |
|
|
3524 | tmp->speed = 0; |
|
|
3525 | update_ob_speed (tmp); |
3530 | } |
3526 | } |
3531 | } |
3527 | } |
|
|
3528 | /* This function can be called everytime a map is loaded, even when |
|
|
3529 | * swapping back in. As such, we don't want to create the treasure |
|
|
3530 | * over and ove again, so after we generate the treasure, blank out |
|
|
3531 | * randomitems so if it is swapped in again, it won't make anything. |
|
|
3532 | * This is a problem for the above objects, because they have counters |
|
|
3533 | * which say how many times to make the treasure. |
|
|
3534 | */ |
|
|
3535 | else if (tmp && tmp->arch && tmp->type != PLAYER |
|
|
3536 | && tmp->type != TREASURE && tmp->type != SPELL |
|
|
3537 | && tmp->type != PLAYER_CHANGER && tmp->type != CLASS |
|
|
3538 | && HAS_RANDOM_ITEMS (tmp)) |
|
|
3539 | { |
|
|
3540 | create_treasure (tmp->randomitems, tmp, GT_APPLY, |
|
|
3541 | m->difficulty, 0); |
|
|
3542 | tmp->randomitems = NULL; |
|
|
3543 | } |
|
|
3544 | } |
3532 | |
3545 | |
3533 | for(x=0;x<MAP_WIDTH(m);x++) |
3546 | for (x = 0; x < MAP_WIDTH (m); x++) |
3534 | for(y=0;y<MAP_HEIGHT(m);y++) |
3547 | for (y = 0; y < MAP_HEIGHT (m); y++) |
3535 | for(tmp=get_map_ob(m,x,y);tmp!=NULL;tmp=tmp->above) |
3548 | for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = tmp->above) |
3536 | if (tmp->above && |
3549 | if (tmp->above && |
3537 | (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL)) |
3550 | (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL)) |
3538 | check_trigger (tmp, tmp->above); |
3551 | check_trigger (tmp, tmp->above); |
3539 | } |
3552 | } |
3540 | |
3553 | |
3541 | /** |
3554 | /** |
3542 | * Handles player eating food that temporarily changes status (resistances, stats). |
3555 | * Handles player eating food that temporarily changes status (resistances, stats). |
3543 | * This used to call cast_change_attr(), but |
3556 | * This used to call cast_change_attr(), but |