/**
 * Removes item from the amount of crates stored in workshops.
 * @param owner
 * @param tngclass
 * @param tngmodel
 * @return Gives WrkCrtS_None if no crate was found, WrkCrtS_Offmap if offmap crate was used, WrkCrtS_Stored if crate from workshop was used.
 * @note was named remove_workshop_item()
 */
int remove_workshop_item_from_amount_stored_f(PlayerNumber plyr_idx, ThingClass tngclass, ThingModel tngmodel, unsigned short flags, const char *func_name)
{
    SYNCDBG(18,"%s: Starting",func_name);
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon_f(plyr_idx,func_name);
    if (dungeon_invalid(dungeon)) {
        ERRORLOG("%s: Can't remove item; player %d has no dungeon.",func_name,(int)plyr_idx);
        return WrkCrtS_None;
    }
    long amount;
    amount = 0;
    switch (tngclass)
    {
    case TCls_Trap:
        if ((flags & WrkCrtF_NoStored) == 0) {
            amount = dungeon->trap_amount_stored[tngmodel];
        }
        if (amount > 0) {
            SYNCDBG(8,"%s: Removing stored trap %s",func_name,trap_code_name(tngmodel));
            dungeon->trap_amount_stored[tngmodel] = amount - 1;
            return WrkCrtS_Stored;
        }
        if ((flags & WrkCrtF_NoOffmap) == 0) {
            amount = dungeon->trap_amount_offmap[tngmodel];
        }
        if (amount > 0) {
            SYNCDBG(8,"%s: Removing offmap trap %s",func_name,trap_code_name(tngmodel));
            dungeon->trap_amount_offmap[tngmodel] = amount - 1;
            return WrkCrtS_Offmap;
        }
        ERRORLOG("%s: Trap %s not available",func_name,trap_code_name(tngmodel));
        break;
    case TCls_Door:
        if ((flags & WrkCrtF_NoStored) == 0) {
            amount = dungeon->door_amount_stored[tngmodel];
        }
        if (amount > 0) {
            SYNCDBG(8,"%s: Removing stored door %s",func_name,door_code_name(tngmodel));
            dungeon->door_amount_stored[tngmodel] = amount - 1;
            return WrkCrtS_Stored;
        }
        if ((flags & WrkCrtF_NoOffmap) == 0) {
            amount = dungeon->door_amount_offmap[tngmodel];
        }
        if (amount > 0) {
            SYNCDBG(8,"%s: Removing offmap door %s",func_name,door_code_name(tngmodel));
            dungeon->door_amount_offmap[tngmodel] = amount - 1;
            return WrkCrtS_Offmap;
        }
        ERRORLOG("%s: Door %s not available",func_name,door_code_name(tngmodel));
        break;
    default:
        ERRORLOG("%s: Can't remove item; illegal item class %d",func_name,(int)tngclass);
        break;
    }
    return WrkCrtS_None;
}
/**
 * Removes item from the amount available to be placed on map.
 * @param owner
 * @param tngclass
 * @param tngmodel
 * @return
 */
TbBool remove_workshop_item_from_amount_placeable_f(PlayerNumber plyr_idx, ThingClass tngclass, ThingModel tngmodel, const char *func_name)
{
    SYNCDBG(18,"%s: Starting",func_name);
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon_f(plyr_idx,func_name);
    if (dungeon_invalid(dungeon)) {
        ERRORLOG("%s: Can't remove item; player %d has no dungeon.",func_name,(int)plyr_idx);
        return false;
    }
    long amount;
    switch (tngclass)
    {
    case TCls_Trap:
        amount = dungeon->trap_amount_placeable[tngmodel];
        if (amount <= 0) {
            ERRORLOG("%s: Trap %s not available",func_name,trap_code_name(tngmodel));
            break;
        }
        SYNCDBG(8,"%s: Removing Trap %s",func_name,trap_code_name(tngmodel));
        dungeon->trap_amount_placeable[tngmodel] = amount - 1;
        dungeon->trap_build_flags[tngmodel] |= MnfBldF_Used;
        dungeon->lvstats.traps_used++;
        return true;
    case TCls_Door:
        amount = dungeon->door_amount_placeable[tngmodel];
        if (amount <= 0) {
            ERRORLOG("%s: Door %s not available",func_name,door_code_name(tngmodel));
            break;
        }
        SYNCDBG(8,"%s: Removing Door %s",func_name,door_code_name(tngmodel));
        dungeon->door_amount_placeable[tngmodel] = amount - 1;
        dungeon->door_build_flags[tngmodel] |= MnfBldF_Used;
        dungeon->lvstats.doors_used++;
        return true;
    default:
        ERRORLOG("%s: Can't remove item; illegal item class %d",func_name,(int)tngclass);
        break;
    }
    return false;
}
/**
 * Adds item to the amount of crates in workshops, but also to the amount available to be placed.
 * @param owner
 * @param tngclass
 * @param tngmodel
 * @return
 * @note was named add_workshop_item()
 */
TbBool add_workshop_item_to_amounts_f(PlayerNumber plyr_idx, ThingClass tngclass, ThingModel tngmodel, const char *func_name)
{
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon_f(plyr_idx,func_name);
    if (dungeon_invalid(dungeon)) {
        ERRORLOG("%s: Can't add item; player %d has no dungeon.",func_name,(int)plyr_idx);
        return false;
    }
    switch (tngclass)
    {
    case TCls_Trap:
        SYNCDBG(8,"%s: Adding Trap %s",func_name,trap_code_name(tngmodel));
        dungeon->trap_amount_stored[tngmodel]++;
        dungeon->trap_amount_placeable[tngmodel]++;
        dungeon->trap_build_flags[tngmodel] |= MnfBldF_Built;
        // In case the placeable amount lost it, do a fix
        if (dungeon->trap_amount_placeable[tngmodel] > dungeon->trap_amount_stored[tngmodel]+dungeon->trap_amount_offmap[tngmodel]) {
            WARNLOG("%s: Placeable %s traps amount for player %d was too large; fixed",func_name,trap_code_name(tngmodel),(int)plyr_idx);
            dungeon->trap_amount_placeable[tngmodel] = dungeon->trap_amount_stored[tngmodel]+dungeon->trap_amount_offmap[tngmodel];
        }
        if (dungeon->trap_amount_placeable[tngmodel] < dungeon->trap_amount_offmap[tngmodel]) {
            WARNLOG("%s: Placeable %s traps amount for player %d was too small; fixed",func_name,trap_code_name(tngmodel),(int)plyr_idx);
            dungeon->trap_amount_placeable[tngmodel] = dungeon->trap_amount_offmap[tngmodel];
        }
        break;
    case TCls_Door:
        SYNCDBG(8,"%s: Adding Door %s",func_name,door_code_name(tngmodel));
        dungeon->door_amount_stored[tngmodel]++;
        dungeon->door_amount_placeable[tngmodel]++;
        dungeon->door_build_flags[tngmodel] |= MnfBldF_Built;
        // In case the placeable amount lost it, do a fix
        if (dungeon->door_amount_placeable[tngmodel] > dungeon->door_amount_stored[tngmodel]+dungeon->door_amount_offmap[tngmodel]) {
            WARNLOG("%s: Placeable %s doors amount for player %d was too large; fixed",func_name,door_code_name(tngmodel),(int)plyr_idx);
            dungeon->door_amount_placeable[tngmodel] = dungeon->door_amount_stored[tngmodel]+dungeon->door_amount_offmap[tngmodel];
        }
        if (dungeon->door_amount_placeable[tngmodel] < dungeon->door_amount_offmap[tngmodel]) {
            WARNLOG("%s: Placeable %s doors amount for player %d was too small; fixed",func_name,door_code_name(tngmodel),(int)plyr_idx);
            dungeon->door_amount_placeable[tngmodel] = dungeon->door_amount_offmap[tngmodel];
        }
        break;
    default:
        ERRORLOG("%s: Can't add item; illegal item class %d",func_name,(int)tngclass);
        return false;
    }
    return true;
}
Beispiel #4
0
struct Thing *create_trap(struct Coord3d *pos, ThingModel trpkind, PlayerNumber plyr_idx)
{
    SYNCDBG(7,"Starting");
    struct TrapStats *trapstat;
    trapstat = &trap_stats[trpkind];
    if (!i_can_allocate_free_thing_structure(FTAF_FreeEffectIfNoSlots)) {
        ERRORDBG(3,"Cannot create trap %s for player %d. There are too many things allocated.",trap_code_name(trpkind),(int)plyr_idx);
        erstat_inc(ESE_NoFreeThings);
        return INVALID_THING;
    }
    struct InitLight ilght;
    LbMemorySet(&ilght, 0, sizeof(struct InitLight));
    struct Thing *thing;
    thing = allocate_free_thing_structure(FTAF_FreeEffectIfNoSlots);
    if (thing->index == 0) {
        ERRORDBG(3,"Should be able to allocate trap %s for player %d, but failed.",trap_code_name(trpkind),(int)plyr_idx);
        erstat_inc(ESE_NoFreeThings);
        return INVALID_THING;
    }
    thing->class_id = TCls_Trap;
    thing->model = trpkind;
    thing->mappos.x.val = pos->x.val;
    thing->mappos.y.val = pos->y.val;
    thing->mappos.z.val = pos->z.val;
    thing->next_on_mapblk = 0;
    thing->parent_idx = thing->index;
    thing->owner = plyr_idx;
    char start_frame;
    if (trapstat->field_13) {
        start_frame = -1;
    } else {
        start_frame = 0;
    }
    set_thing_draw(thing, trapstat->field_4, trapstat->field_D, trapstat->field_8, trapstat->field_C, start_frame, 2);
    if (trapstat->field_11) {
        thing->field_4F |= 0x02;
    } else {
        thing->field_4F &= ~0x02;
    }
    if (trapstat->field_C) {
        thing->field_4F |= 0x40;
    } else {
        thing->field_4F &= ~0x40;
    }
    thing->clipbox_size_xy = trapstat->size_xy;
    thing->clipbox_size_yz = trapstat->field_16;
    thing->solid_size_xy = trapstat->size_xy;
    thing->field_5C = trapstat->field_16;
    thing->creation_turn = game.play_gameturn;
    thing->health = trapstat->field_0;
    thing->field_4F &= ~0x10;
    thing->field_4F |= 0x20;
    thing->byte_13 = 0;
    thing->long_14 = game.play_gameturn;
    if (trapstat->field_1C != 0)
    {
        ilght.mappos.x.val = thing->mappos.x.val;
        ilght.mappos.y.val = thing->mappos.y.val;
        ilght.mappos.z.val = thing->mappos.z.val;
        ilght.field_0 = trapstat->field_1C;
        ilght.field_2 = trapstat->field_1E;
        ilght.is_dynamic = 1;
        ilght.field_3 = trapstat->field_1F;
        thing->light_id = light_create_light(&ilght);
        if (thing->light_id <= 0) {
            SYNCDBG(8,"Cannot allocate dynamic light to %s.",thing_model_name(thing));
        }
    }
    add_thing_to_its_class_list(thing);
    place_thing_in_mapwho(thing);
    return thing;
}