void activate_trap(struct Thing *traptng, struct Thing *creatng) { const struct TrapStats *trapstat; traptng->trap.byte_18t = 1; trapstat = &trap_stats[traptng->model]; //TODO CONFIG trap model dependency, make config option instead if (traptng->model == 2) { event_create_event(traptng->mappos.x.val, traptng->mappos.y.val, EvKind_AlarmTriggered, traptng->owner, 0); } thing_play_sample(traptng, 176, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); switch (trapstat->activation_type) { case 1: activate_trap_shot_head_for_target90(traptng, creatng); break; case 2: activate_trap_effect_on_trap(traptng, creatng); break; case 3: activate_trap_shot_on_trap(traptng, creatng); break; case 4: activate_trap_slab_change(traptng, creatng); break; default: ERRORLOG("Illegal trap activation type %d",(int)trapstat->activation_type); break; } }
TbBool mark_creature_joined_dungeon(struct Thing *creatng) { if (creatng->owner == game.neutral_player_num) { // Neutral player has no dungeon return false; } struct Dungeon *dungeon; dungeon = get_dungeon(creatng->owner); if (dungeon_invalid(dungeon)) { ERRORLOG("Can't mark; player %d has no dungeon",(int)creatng->owner); return false; } if ((dungeon->owned_creatures_of_model[creatng->model] <= 1) && (dungeon->creature_models_joined[creatng->model] <= 0)) { event_create_event(creatng->mappos.x.val, creatng->mappos.y.val, EvKind_NewCreature, creatng->owner, creatng->index); } if (dungeon->creature_models_joined[creatng->model] < 255) { dungeon->creature_models_joined[creatng->model]++; } return true; }
TbBool process_scavenge_creature_from_level(struct Thing *scavtng, struct Thing *calltng, long work_value) { struct Dungeon *calldngn; long num_prayers; calldngn = get_dungeon(calltng->owner); if (dungeon_invalid(calldngn)) { ERRORLOG("The %s owner %d can't do scavenging - has no dungeon",thing_model_name(calltng),(int)calltng->owner); return false; } // Compute amount of creatures praying against the scavenge if (!is_neutral_thing(scavtng)) { struct Dungeon *scavdngn; scavdngn = get_dungeon(scavtng->owner); num_prayers = scavdngn->creatures_praying[scavtng->model]; } else { num_prayers = 0; } // Increase scavenging counter, used to break the prayers counter calldngn->creatures_scavenging[scavtng->model]++; // If scavenge is blocked by prayers, return if (calldngn->creatures_scavenging[calltng->model] < 2 * num_prayers) { SYNCDBG(8, "Player %d prayers (%d) are blocking player %d scavenging (%d) of %s", (int)scavtng->owner, (int)num_prayers, (int)calltng->owner, (int)calldngn->creatures_scavenging[calltng->model], thing_model_name(calltng)); return false; } SYNCDBG(18,"The %s index %d scavenges %s index %d",thing_model_name(calltng),(int)calltng->index,thing_model_name(scavtng),(int)scavtng->index); // If we're starting to scavenge a new creature, do the switch if (calldngn->scavenge_targets[calltng->model] != scavtng->index) { calldngn->scavenge_turn_points[calltng->model] = work_value; if (calldngn->scavenge_targets[calltng->model] > 0) { // Stop scavenging old creature struct Thing *thing; thing = thing_get(calldngn->scavenge_targets[calltng->model]); if (thing_is_creature(thing) && (thing->model == calltng->model)) { if (creature_is_being_scavenged(thing)) { set_start_state(thing); } } } // Start the new scavenging calldngn->scavenge_targets[calltng->model] = scavtng->index; if (is_my_player_number(scavtng->owner)) { output_message(SMsg_CreatureScanvenged, 500, 1); } event_create_event(scavtng->mappos.x.val, scavtng->mappos.y.val, EvKind_CreatrScavenged, scavtng->owner, scavtng->index); } else { calldngn->scavenge_turn_points[calltng->model] += work_value; } // Make sure the scavenged creature is in correct state if (!creature_is_being_scavenged(scavtng)) { if (!is_neutral_thing(scavtng)) { external_set_thing_state(scavtng, CrSt_CreatureBeingScavenged); } } long scavpts; scavpts = calculate_correct_creature_scavenge_required(scavtng, calltng->owner); if ((scavpts << 8) < calldngn->scavenge_turn_points[calltng->model]) { SYNCDBG(8,"The %s index %d owner %d accumulated enough points to turn to scavenger",thing_model_name(scavtng),(int)scavtng->index,(int)scavtng->owner); turn_creature_to_scavenger(scavtng, calltng); calldngn->scavenge_turn_points[calltng->model] -= (scavpts << 8); return true; } return false; }
TbBool create_workshop_object_in_workshop_room(PlayerNumber plyr_idx, ThingClass tngclass, ThingModel tngmodel) { struct Coord3d pos; struct Thing *cratetng; struct Room *room; struct Dungeon *dungeon; SYNCDBG(7,"Making player %d new %s",(int)plyr_idx,thing_class_code_name(tngclass)); pos.x.val = 0; pos.y.val = 0; pos.z.val = 0; switch (tngclass) { case TCls_Trap: cratetng = create_object(&pos, trap_crate_object_model(tngmodel), plyr_idx, -1); break; case TCls_Door: cratetng = create_object(&pos, door_crate_object_model(tngmodel), plyr_idx, -1); break; default: cratetng = INVALID_THING; ERRORLOG("No known workshop crate can represent %s model %d",thing_class_code_name(tngclass),(int)tngmodel); break; } if (thing_is_invalid(cratetng)) { ERRORLOG("Could not create workshop crate thing for %s",thing_class_code_name(tngclass)); return false; } room = find_random_room_for_thing_with_spare_room_item_capacity(cratetng, plyr_idx, RoK_WORKSHOP, 0); if (room_is_invalid(room)) { ERRORLOG("No %s room found which would accept %s crate",room_code_name(RoK_WORKSHOP),thing_class_code_name(tngclass)); destroy_object(cratetng); return false; } if (!find_random_valid_position_for_thing_in_room_avoiding_object(cratetng, room, &pos)) { ERRORLOG("Could not find a place in %s index %d for the new %s crate", room_code_name(room->kind),(int)room->index,thing_class_code_name(tngclass)); destroy_object(cratetng); return false; } pos.z.val = get_thing_height_at(cratetng, &pos); move_thing_in_map(cratetng, &pos); if (!add_workshop_object_to_workshop(room, cratetng)) { ERRORLOG("Could not fit %s crate in %s index %d", thing_class_code_name(tngclass),room_code_name(room->kind),(int)room->index); destroy_object(cratetng); return false; } dungeon = get_players_num_dungeon(plyr_idx); switch (tngclass) { case TCls_Trap: if ((dungeon->trap_build_flags[tngmodel] & MnfBldF_Built) == 0) { event_create_event(cratetng->mappos.x.val, cratetng->mappos.y.val, EvKind_NewTrap, plyr_idx, tngmodel); } break; case TCls_Door: if ((dungeon->door_build_flags[tngmodel] & MnfBldF_Built) == 0) { event_create_event(cratetng->mappos.x.val, cratetng->mappos.y.val, EvKind_NewDoor, plyr_idx, tngmodel); } break; default: break; } create_effect(&pos, TngEff_Unknown56, cratetng->owner); thing_play_sample(cratetng, 89, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); return true; }