TbBool prison_convert_creature_to_skeleton(struct Room *room, struct Thing *thing) { struct Dungeon *dungeon; struct CreatureControl *cctrl; struct Thing *crthing; long crmodel; cctrl = creature_control_get_from_thing(thing); crmodel = get_room_create_creature_model(room->kind); // That normally returns skeleton breed crthing = create_creature(&thing->mappos, crmodel, room->owner); if (thing_is_invalid(crthing)) { ERRORLOG("Couldn't create creature %s in prison", creature_code_name(crmodel)); return false; } init_creature_level(crthing, cctrl->explevel); set_start_state(crthing); if (creature_model_bleeds(thing->model)) create_effect_around_thing(thing, TngEff_Unknown10); kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects); dungeon = get_dungeon(room->owner); if (!dungeon_invalid(dungeon)) { dungeon->lvstats.skeletons_raised++; } return true; }
struct Thing *create_and_control_creature_as_controller(struct PlayerInfo *player, long breed, struct Coord3d *pos) { struct CreatureStats *crstat; struct CreatureControl *cctrl; struct Dungeon *dungeon; struct Thing *thing; struct Camera *cam; struct InitLight ilght; SYNCDBG(6,"Request for model %ld at (%d,%d,%d)",breed,(int)pos->x.val,(int)pos->y.val,(int)pos->z.val); //return _DK_create_and_control_creature_as_controller(player, a2, pos); thing = create_creature(pos, breed, player->id_number); if (thing_is_invalid(thing)) return INVALID_THING; dungeon = get_dungeon(thing->owner); dungeon->num_active_creatrs--; dungeon->owned_creatures_of_model[thing->model]--; if (is_my_player(player)) { toggle_status_menu(0); turn_off_roaming_menus(); } cam = player->acamera; player->controlled_thing_idx = thing->index; player->field_31 = thing->creation_turn; player->field_4B5 = cam->field_6; thing->alloc_flags |= TAlF_IsControlled; thing->field_4F |= 0x01; cctrl = creature_control_get_from_thing(thing); cctrl->flgfield_2 |= 0x02; cctrl->max_speed = calculate_correct_creature_maxspeed(thing); set_player_mode(player, PVT_CreatureContrl); set_start_state(thing); // Preparing light object LbMemorySet(&ilght, 0, sizeof(struct InitLight)); 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_2 = 36; ilght.field_3 = 1; ilght.is_dynamic = 1; ilght.field_0 = 2560; thing->light_id = light_create_light(&ilght); if (thing->light_id != 0) { light_set_light_never_cache(thing->light_id); } else { ERRORLOG("Cannot allocate light to new hero"); } if (is_my_player_number(thing->owner)) { if (thing->class_id == TCls_Creature) { crstat = creature_stats_get_from_thing(thing); setup_eye_lens(crstat->eye_effect); } } return thing; }
creature_t* creature_t::create_creature_by_name(const char* name) { for (size_t i = 0; i < CREATURES.size(); i++) { if (!strcmp(CREATURES[i].name, name)) { creature_t* creature = create_creature(i); return creature; } } return nullptr; }
TbBool create_transferred_creature_on_level(void) { struct Thing *thing; struct Coord3d *pos; if (game.intralvl_transfered_creature.model > 0) { thing = get_player_soul_container(my_player_number); pos = &(thing->mappos); thing = create_creature(pos, game.intralvl_transfered_creature.model, 5); if (thing_is_invalid(thing)) return false; init_creature_level(thing, game.intralvl_transfered_creature.explevel); clear_transfered_creature(); return true; } return false; }
// ----------------------------------------------------------------------- // handler for the Animate Dead spells // ----------------------------------------------------------------------- void t_animate_dead::resurrect( t_combat_creature_ptr creature ) { // find a suitably large open spot t_combat_creature& caster = *get_caster(); double scale = m_battlefield.get_model_scale(); bool defender = caster.get_controller(); t_combat_creature_ptr new_creature; m_spell_target = creature; new_creature = create_creature( creature, scale, defender ); new_creature->set_number( 0 ); // find closest point to place this creature if (!place_summoned_creature( caster, new_creature )) return; if (!m_is_artifact) get_caster()->set_default_spell( m_spell ); m_battlefield.begin_spell( creature ); }
void resurrect_creature(struct Thing *boxtng, PlayerNumber owner, ThingModel crmodel, unsigned char crlevel) { struct Thing *creatng; if (!thing_exists(boxtng) || (box_thing_to_special(boxtng) != SpcKind_Resurrect) ) { ERRORMSG("Invalid resurrect box object!"); return; } creatng = create_creature(&boxtng->mappos, crmodel, owner); if (!thing_is_invalid(creatng)) { init_creature_level(creatng, crlevel); if (is_my_player_number(owner)) output_message(SMsg_CommonAcknowledge, 0, true); } create_special_used_effect(&boxtng->mappos, owner); remove_events_thing_is_attached_to(boxtng); force_any_creature_dragging_owned_thing_to_drop_it(boxtng); if ((gameadd.classic_bugs_flags & ClscBug_ResurrectForever) == 0) { remove_item_from_dead_creature_list(get_players_num_dungeon(owner), crmodel, crlevel); } delete_thing_structure(boxtng, 0); }
struct Thing *create_thing(struct Coord3d *pos, unsigned short tngclass, unsigned short model, unsigned short owner, long parent_idx) { struct Thing *thing; //return _DK_create_thing(pos, tngclass, model, owner, a4); thing = INVALID_THING; switch (tngclass) { case TCls_Object: thing = create_object(pos, model, owner, parent_idx); break; case TCls_Shot: thing = create_shot(pos, model, owner); break; case TCls_EffectElem: thing = create_effect_element(pos, model, owner); break; case TCls_DeadCreature: thing = create_dead_creature(pos, model, 1, owner, 0); break; case TCls_Creature: thing = create_creature(pos, model, owner); break; case TCls_Effect: thing = create_effect(pos, model, owner); break; case TCls_Trap: thing = create_trap(pos, model, owner); break; case TCls_AmbientSnd: thing = create_ambient_sound(pos, model, owner); break; case TCls_CaveIn: thing = create_cave_in(pos, model, owner); break; default: break; } return thing; }
void multiply_creatures_in_dungeon_list(struct Dungeon *dungeon, long list_start) { struct Thing *thing; struct Thing *tncopy; struct CreatureControl *cctrl; unsigned long k; int i; k = 0; i = list_start; while (i != 0) { thing = thing_get(i); cctrl = creature_control_get_from_thing(thing); if (thing_is_invalid(thing) || creature_control_invalid(cctrl)) { ERRORLOG("Jump to invalid creature detected"); break; } i = cctrl->players_next_creature_idx; // Thing list loop body tncopy = create_creature(&thing->mappos, thing->model, dungeon->owner); if (thing_is_invalid(tncopy)) { WARNLOG("Can't create a copy of creature"); break; } set_creature_level(tncopy, cctrl->explevel); tncopy->health = thing->health; // Thing list loop body ends k++; if (k > CREATURES_COUNT) { ERRORLOG("Infinite loop detected when sweeping creatures list"); erstat_inc(ESE_InfChainTngPerOwner); break; } } }
TbBool creature_scavenge_from_creature_pool(struct Thing *calltng) { struct Room *room; struct Coord3d pos; room = get_room_thing_is_on(calltng); if (!room_initially_valid_as_type_for_thing(room, RoK_SCAVENGER, calltng)) { WARNLOG("Room %s owned by player %d is bad work place for %s owned by played %d",room_code_name(room->kind),(int)room->owner,thing_model_name(calltng),(int)calltng->owner); return false; } if (game.pool.crtr_kind[calltng->model] <= 0) { ERRORLOG("Tried to generate %s but it is not in pool",thing_model_name(calltng)); return false; } if ( !find_random_valid_position_for_thing_in_room(calltng, room, &pos) ) { ERRORLOG("Could not find valid position for thing to be generated"); return false; } struct Thing *scavtng; scavtng = create_creature(&pos, calltng->model, calltng->owner); if (thing_is_invalid(scavtng)) { ERRORLOG("Tried to generate %s but creation failed",thing_model_name(calltng)); return false; } if (!remove_creature_from_generate_pool(calltng->model)) { ERRORLOG("Could not remove %s from pool",thing_model_name(calltng)); return false; } { struct Dungeon *dungeon; dungeon = get_dungeon(calltng->owner); dungeon->creatures_scavenge_gain++; } internal_set_thing_state(scavtng, CrSt_CreatureScavengedReappear); return true; }
void roguelike() { enum { KEY_ESC = 27, KEY_ENTER = '\r', KEY_BACKSPACE = 8, CTRL_S = 19, CTRL_P = 16, CTRL_Q = 17, CTRL_B = 2, KEY_UP = 72, KEY_DOWN = 80, KEY_LEFT = 75, KEY_RIGHT = 77}; char screenmap[info.screenheight][info.screenwidth+1]; //y then x memset(screenmap, ' ', (info.screenwidth+1)*info.screenheight); struct creature * critters = create_creature("playa", '@', LIGHTGRAY, 16+((info.screenwidth-16)/2), info.screenheight/2); struct creature * head = critters; head->next = create_creature("monsu", 'M', RED, 16+20, 20); /* store player for convenience*/ struct creature * player = critters; //construct terrain // for (int i = 0; i <2; i++){ // terrain[i].character = symbols[i][0]; // terrain[i].color = symbols[i][1]; // } for (int i = 3; i <256; i++){ // zero unused values // terrain[i].name="undefined"; terrain[i].character = 0; terrain[i].color = 0; } int val; // getch value clrscr(); char * title[] = {"Roguelike", "Press Any Key"}; for (int i=0; i!=2; i++){ gotoxy((info.screenwidth-(strchr(title[i], '\0')-title[i]))/2, -3+i+info.screenheight/2); printf("%s", title[i]); } getch(); clrscr(); for (int i = 0; i < info.screenheight-1; i++){ screenmap[i][15] = '|'; screenmap[i][0] = '*'; screenmap[i][info.screenwidth-1] = '*'; screenmap[i][info.screenwidth]='\0'; } for (int i = 0; i < info.screenwidth; i++){ screenmap[0][i] = '*'; screenmap[info.screenheight-2][i] = '*'; } //let's make a lawn for (int y=1; y < info.screenheight-2; y++) { for (int x=16; x < info.screenwidth-1; x++) { screenmap[y][x] = (90 < rand() % 100) ? WATER : GRASS; } } // a wall.... // for (int x=20; x<30;x++){ screenmap[5][x] = WALL; screenmap[15][x] = WALL; } for (int y=5; y<15;y++){ screenmap[y][20] = WALL; screenmap[y][30] = WALL; } textcolor(WHITE); full_refresh(&screenmap[0][0], terrain); draw_creatures(head); gotoxy(0,0); _setcursortype(_NOCURSOR); _setcursortype(0); while((val=getch())!=CTRL_Q) { erase_creatures(head, &screenmap[0][0], terrain); player = handle_input(val, player, (char *)screenmap); head = update_creature_position(head, player->name, player->x, player->y); draw_creatures(head); textcolor(WHITE); putchxy(2, 2, ':'); printf("Test"); _setcursortype(_NOCURSOR); _setcursortype(0); } _setcursortype(_NORMALCURSOR); textcolor(YELLOW); }
TbBool steal_hero(struct PlayerInfo *player, struct Coord3d *pos) { //TODO CONFIG creature models dependency; put them in config files static ThingModel skip_steal_models[] = {6, 7}; static ThingModel prefer_steal_models[] = {3, 12}; struct Thing *herotng; herotng = INVALID_THING; int heronum; struct Dungeon *herodngn; struct CreatureControl *cctrl; unsigned long k; int i; SYNCDBG(8,"Starting"); herodngn = get_players_num_dungeon(game.hero_player_num); k = 0; if (herodngn->num_active_creatrs > 0) { heronum = ACTION_RANDOM(herodngn->num_active_creatrs); i = herodngn->creatr_list_start; SYNCDBG(4,"Selecting random creature %d out of %d heroes",(int)heronum,(int)herodngn->num_active_creatrs); } else { heronum = 0; i = 0; SYNCDBG(4,"No heroes on map, skipping selection"); } while (i != 0) { struct Thing *thing; thing = thing_get(i); TRACE_THING(thing); cctrl = creature_control_get_from_thing(thing); if (thing_is_invalid(thing) || creature_control_invalid(cctrl)) { ERRORLOG("Jump to invalid creature detected"); break; } i = cctrl->players_next_creature_idx; // Thing list loop body TbBool heroallow; heroallow = true; ThingModel skipidx; for (skipidx=0; skipidx < sizeof(skip_steal_models)/sizeof(skip_steal_models[0]); skipidx++) { if (thing->model == skip_steal_models[skipidx]) { heroallow = false; } } if (heroallow) { herotng = thing; } // If we've reached requested hero number, return either current hero on previously selected one if ((heronum <= 0) && thing_is_creature(herotng)) { break; } heronum--; if (i == 0) { i = herodngn->creatr_list_start; } // Thing list loop body ends k++; if (k > CREATURES_COUNT) { ERRORLOG("Infinite loop detected when sweeping creatures list"); erstat_inc(ESE_InfChainTngPerOwner); break; } } if (!thing_is_invalid(herotng)) { move_thing_in_map(herotng, pos); change_creature_owner(herotng, player->id_number); SYNCDBG(3,"Converted %s to owner %d",thing_model_name(herotng),(int)player->id_number); } else { i = ACTION_RANDOM(sizeof(prefer_steal_models)/sizeof(prefer_steal_models[0])); struct Thing *creatng; creatng = create_creature(pos, prefer_steal_models[i], player->id_number); if (thing_is_invalid(creatng)) return false; SYNCDBG(3,"Created %s owner %d",thing_model_name(creatng),(int)player->id_number); } return true; }
short thing_create_thing(struct InitThing *itng) { struct Thing *thing; if (itng->owner == 7) { ERRORLOG("Invalid owning player %d, fixing to %d", (int)itng->owner, (int)game.hero_player_num); itng->owner = game.hero_player_num; } else if (itng->owner == 8) { ERRORLOG("Invalid owning player %d, fixing to %d", (int)itng->owner, (int)game.neutral_player_num); itng->owner = game.neutral_player_num; } if (itng->owner > 5) { ERRORLOG("Invalid owning player %d, thing discarded", (int)itng->owner); return false; } switch (itng->oclass) { case TCls_Object: thing = create_thing(&itng->mappos, itng->oclass, itng->model, itng->owner, itng->index); if (!thing_is_invalid(thing)) { if (itng->model == 49) //HERO_GATE thing->byte_13 = itng->params[1]; check_and_asimilate_thing_by_room(thing); // make sure we don't have invalid pointer thing = INVALID_THING; } else { ERRORLOG("Couldn't create object model %d", (int)itng->model); return false; } break; case TCls_Creature: thing = create_creature(&itng->mappos, itng->model, itng->owner); if (thing_is_invalid(thing)) { ERRORLOG("Couldn't create creature model %d", (int)itng->model); return false; } init_creature_level(thing, itng->params[1]); break; case TCls_EffectGen: thing = create_effect_generator(&itng->mappos, itng->model, itng->range, itng->owner, itng->index); if (thing_is_invalid(thing)) { ERRORLOG("Couldn't create effect generator model %d", (int)itng->model); return false; } break; case TCls_Trap: thing = create_thing(&itng->mappos, itng->oclass, itng->model, itng->owner, itng->index); if (thing_is_invalid(thing)) { ERRORLOG("Couldn't create trap model %d", (int)itng->model); return false; } break; case TCls_Door: thing = create_door(&itng->mappos, itng->model, itng->params[0], itng->owner, itng->params[1]); if (thing_is_invalid(thing)) { ERRORLOG("Couldn't create door model %d", (int)itng->model); return false; } break; case 10: case 11: thing = create_thing(&itng->mappos, itng->oclass, itng->model, itng->owner, itng->index); if (thing_is_invalid(thing)) { ERRORLOG("Couldn't create thing class %d model %d", (int)itng->oclass, (int)itng->model); return false; } break; default: ERRORLOG("Invalid class %d, thing discarded", (int)itng->oclass); return false; } return true; }
// ----------------------------------------------------------------------- // handler for the Animate Dead spells // ----------------------------------------------------------------------- void t_animate_dead::cast_and_mirror( t_combat_creature_ptr target, int power ) { t_battlefield& battlefield = m_battlefield; t_combat_action_message message( *m_caster, get_action_text( false ) ); battlefield.start_animation( *target, m_spell, message ); int number = get_bodies_affected( target ); t_direction direction; int health = get_health_power( *target ); // find a suitably large open spot t_combat_creature& caster = *get_caster(); double scale = battlefield.get_model_scale(); bool defender = caster.get_controller(); t_combat_creature_ptr creature; creature = battlefield.find_summoned_creature( m_spell, get_creature_type( *target ), caster.get_controller() ); if (creature != 0) { creature->add_creatures( health ); if (target->get_number() == 0 && target->get_salvageable_bodies() <= number) target->fade_out( message ); } else { creature = create_creature( target, scale, defender ); creature->set_number( 0 ); if (!place_summoned_creature( caster, creature )) return; // check if there are no bodies left if (target->get_number() == 0 && target->get_salvageable_bodies() <= number) { // if the creature is not in the same cell... if (target->get_cell_position() != creature->get_cell_position() || target->get_creature_type() != creature->get_creature_type()) target->fade_out( message ); else { // if there are no bodies left, hide the target and replace it with the new creature target->set_alpha( m_battlefield, 0 ); // make the creature face the same direction as the target direction = target->get_current_direction(); creature->set_current_direction( direction ); creature->set_alpha( m_battlefield, 15 ); } target->set_normal_alpha( 0 ); } // play death animation in reverse creature->set_current_action( k_combat_actor_action_die ); creature->set_spell( m_spell, message ); battlefield.place_object( creature, t_map_point_2d( creature->get_position() )); creature->show_resurrection( message ); } // remove bodies from target target->remove_bodies( number ); creature->resurrect( health ); play_sound(); // if creature is invisible, fade it in. if (creature->get_alpha() < 15) creature->fade_in( message ); battlefield.set_spell( 0 ); }