static void frame_trigger(sprite_t *s) { if (s->state & PLANE_ACCELERATING && s->owner->isConnected) { if (((mech_sprite_t *)s)->damage < 10){ /*FUME*/ if(s->owner->schrodinger==1){ create_effect(&puff,s->x,s->y); } } else create_effect(&blacksmoke,s->x,s->y); } }
long instf_attack_room_slab(struct Thing *creatng, long *param) { TRACE_THING(creatng); //return _DK_instf_attack_room_slab(creatng, param); struct Room *room; room = get_room_thing_is_on(creatng); if (room_is_invalid(room)) { ERRORLOG("The %s is not on room",thing_model_name(creatng)); return 0; } struct SlabMap *slb; slb = get_slabmap_thing_is_on(creatng); if (slb->health > 2) { //TODO CONFIG damage made to room slabs is constant - doesn't look good slb->health -= 2; thing_play_sample(creatng, 128 + UNSYNC_RANDOM(3), NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); return 1; } if (room->owner != game.neutral_player_num) { struct Dungeon *dungeon; dungeon = get_dungeon(room->owner); dungeon->rooms_destroyed++; } if (!delete_room_slab(coord_slab(creatng->mappos.x.val), coord_slab(creatng->mappos.y.val), 1)) { ERRORLOG("Cannot delete %s room tile destroyed by %s",room_code_name(room->kind),thing_model_name(creatng)); return 0; } create_effect(&creatng->mappos, 3, creatng->owner); thing_play_sample(creatng, 47, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); return 1; }
long creature_add_lair_to_room(struct Thing *creatng, struct Room *room) { struct Thing *lairtng; if (!room_has_enough_free_capacity_for_creature(room, creatng)) return 0; //return _DK_creature_add_lair_to_room(thing, room); // Make sure we don't already have a lair on that position lairtng = find_creature_lair_at_subtile(creatng->mappos.x.stl.num, creatng->mappos.y.stl.num, 0); if (!thing_is_invalid(lairtng)) return 0; struct CreatureStats *crstat; struct CreatureControl *cctrl; crstat = creature_stats_get_from_thing(creatng); cctrl = creature_control_get_from_thing(creatng); room->content_per_model[creatng->model]++; room->used_capacity += crstat->lair_size; if ((cctrl->lair_room_id > 0) && (cctrl->lairtng_idx > 0)) { struct Room *room; room = room_get(cctrl->lair_room_id); creature_remove_lair_from_room(creatng, room); } cctrl->lair_room_id = room->index; // Create the lair thing struct CreatureData *crdata; struct Coord3d pos; pos.x.val = creatng->mappos.x.val; pos.y.val = creatng->mappos.y.val; pos.z.val = creatng->mappos.z.val; crdata = creature_data_get_from_thing(creatng); lairtng = create_object(&pos, crdata->field_1, creatng->owner, -1); if (thing_is_invalid(lairtng)) { ERRORLOG("Could not create lair totem"); remove_thing_from_mapwho(creatng); place_thing_in_mapwho(creatng); return 1; // Return that so we won't try to redo the action over and over } lairtng->mappos.z.val = get_thing_height_at(lairtng, &lairtng->mappos); // Associate creature with the lair cctrl->lairtng_idx = lairtng->index; lairtng->word_13 = creatng->index; lairtng->word_15 = 1; // Lair size depends on creature level lairtng->word_17 = 300 * cctrl->explevel / 20 + 300; lairtng->field_52 = ACTION_RANDOM(0x800); struct Objects *objdat; unsigned long i; objdat = get_objects_data_for_thing(lairtng); i = convert_td_iso(objdat->field_5); set_thing_draw(lairtng, i, objdat->field_7, lairtng->word_15, 0, -1, objdat->field_11); thing_play_sample(creatng, 158, NORMAL_PITCH, 0, 3, 1, 2, FULL_LOUDNESS); create_effect(&pos, imp_spangle_effects[creatng->owner], creatng->owner); anger_set_creature_anger(creatng, 0, AngR_NoLair); remove_thing_from_mapwho(creatng); place_thing_in_mapwho(creatng); return 1; }
static void crashing_trigger(sprite_t *s) { sprite_t *p; float v[2] = {0,-20}; p = sprite_create(&blacksmoke,NULL); sprite_set_pos(p,s->x,s->y); sprite_set_vel(p,v); sprite_group_insert(effects_group,p); create_effect(&fire,s->x,s->y); }
long instf_fart(struct Thing *creatng, long *param) { TRACE_THING(creatng); //return _DK_instf_fart(creatng, param); struct Thing *efftng; efftng = create_effect(&creatng->mappos, 13, creatng->owner); if (!thing_is_invalid(efftng)) efftng->byte_16 = 4; thing_play_sample(creatng,94+UNSYNC_RANDOM(6), NORMAL_PITCH, 0, 3, 0, 4, FULL_LOUDNESS); return 1; }
void meta_effect_run_focus (MetaWindow *window, MetaEffectFinished finished, gpointer data) { MetaEffect *effect; g_return_if_fail (window != NULL); effect = create_effect (META_EFFECT_FOCUS, window, finished, data); run_handler (effect); }
void creature_t::apply_poison_to() { if (!(get_active_effects_for(this) & EF_POISON)) { int poison_resistance = compute_resistance(ELEMENT_POISON); int poison_roll = roll_dice("1d100"); if (poison_roll > poison_resistance) { create_effect(this, EF_POISON, 8, 1); } } }
short creature_scavenged_disappear(struct Thing *thing) { struct CreatureControl *cctrl; struct Dungeon *dungeon; struct Room *room; struct Coord3d pos; long stl_x, stl_y; long i; //return _DK_creature_scavenged_disappear(thing); cctrl = creature_control_get_from_thing(thing); cctrl->byte_9A--; if (cctrl->byte_9A > 0) { if ((cctrl->byte_9A == 7) && (cctrl->byte_9B < PLAYERS_COUNT)) { create_effect(&thing->mappos, get_scavenge_effect_element(cctrl->byte_9B), thing->owner); } return 0; } // We don't really have to convert coordinates into numbers and back to XY. i = get_subtile_number(cctrl->scavenge.stl_9D_x, cctrl->scavenge.stl_9D_y); stl_x = stl_num_decode_x(i); stl_y = stl_num_decode_y(i); room = subtile_room_get(stl_x, stl_y); if (room_is_invalid(room) || (room->kind != RoK_SCAVENGER)) { ERRORLOG("Room %s at (%d,%d) disappeared.",room_code_name(RoK_SCAVENGER),(int)stl_x,(int)stl_y); kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects); return -1; } if (find_random_valid_position_for_thing_in_room(thing, room, &pos)) { move_thing_in_map(thing, &pos); anger_set_creature_anger_all_types(thing, 0); dungeon = get_dungeon(cctrl->byte_9B); dungeon->creatures_scavenge_gain++; if (is_my_player_number(thing->owner)) output_message(SMsg_MinionScanvenged, 0, true); cctrl->byte_9C = thing->owner; change_creature_owner(thing, cctrl->byte_9B); internal_set_thing_state(thing, CrSt_CreatureScavengedReappear); return 0; } else { ERRORLOG("No valid position inside %s room for %s.",room_code_name(room->kind),thing_model_name(thing)); kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects); return -1; } }
void process_armageddon_influencing_creature(struct Thing *creatng) { if (game.armageddon_cast_turn != 0) { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); // If Armageddon is on, teleport creature to its position if ((cctrl->armageddon_teleport_turn != 0) && (cctrl->armageddon_teleport_turn <= game.play_gameturn)) { cctrl->armageddon_teleport_turn = 0; create_effect(&creatng->mappos, imp_spangle_effects[creatng->owner], creatng->owner); move_thing_in_map(creatng, &game.armageddon.mappos); } } }
void activate_trap_effect_on_trap(struct Thing *traptng, struct Thing *creatng) { struct TrapStats *trapstat; trapstat = &trap_stats[traptng->model]; if (trapstat->field_1A <= 0) { ERRORLOG("Trap activation of bad effect kind %d",(int)trapstat->field_1A); return; } struct Thing *efftng; efftng = create_effect(&traptng->mappos, trapstat->field_1A, traptng->owner); if (!thing_is_invalid(efftng)) { efftng->byte_16 = trapstat->field_1B; SYNCDBG(18,"Created %s",thing_model_name(efftng)); } }
bool t_artifact::read( std::streambuf& buffer ) { int i; int size; int version = get<t_int16>( buffer ); if (version < k_current_version) { m_icon = t_artifact_type( version ); version = 0; } else { if (version > k_current_version) return false; m_icon = t_artifact_type( get<t_int16>(buffer) ); } if (m_icon == k_artifact_none) return true; if (m_icon >= k_artifact_type_count) return false; m_level = t_artifact_level( get<t_uint8>(buffer) ); size = get<t_uint16>( buffer ); m_effects.clear(); m_effects.reserve( size ); for (i = 0; i < size; i++) { t_artifact_effect_type type = t_artifact_effect_type( get<t_uint8>( buffer ) ); t_artifact_effect_ptr effect = create_effect( type ); if (!effect->read( buffer )) return false; m_effects.push_back( effect ); } read_string16( buffer, m_help_text ); read_string16( buffer, m_name ); if (version >= 10000) read_string16( buffer, m_name_with_article ); else m_name_with_article = m_name; read_string16( buffer, m_pickup_text ); return true; }
long instf_reinforce(struct Thing *creatng, long *param) { struct CreatureControl *cctrl; SYNCDBG(16,"Starting"); TRACE_THING(creatng); //return _DK_instf_reinforce(creatng, param); cctrl = creature_control_get_from_thing(creatng); MapSubtlCoord stl_x,stl_y; MapSlabCoord slb_x,slb_y; stl_x = stl_num_decode_x(cctrl->digger.working_stl); stl_y = stl_num_decode_y(cctrl->digger.working_stl); slb_x = subtile_slab_fast(stl_x); slb_y = subtile_slab_fast(stl_y); if (check_place_to_reinforce(creatng, slb_x, slb_y) <= 0) { return 0; } if (cctrl->digger.byte_93 <= 25) { cctrl->digger.byte_93++; if (!S3DEmitterIsPlayingSample(creatng->snd_emitter_id, 172, 0)) { thing_play_sample(creatng, 172, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); } return 0; } cctrl->digger.byte_93 = 0; place_and_process_pretty_wall_slab(creatng, slb_x, slb_y); struct Coord3d pos; pos.x.stl.pos = 128; pos.y.stl.pos = 128; pos.z.stl.pos = 128; long n; for (n=0; n < SMALL_AROUND_LENGTH; n++) { pos.x.stl.num = stl_x + 2 * small_around[n].delta_x; pos.y.stl.num = stl_y + 2 * small_around[n].delta_y; struct Map *mapblk; mapblk = get_map_block_at(pos.x.stl.num, pos.y.stl.num); if (map_block_revealed(mapblk, creatng->owner) && ((mapblk->flags & MapFlg_IsTall) == 0)) { pos.z.val = get_floor_height_at(&pos); create_effect(&pos, imp_spangle_effects[creatng->owner], creatng->owner); } } thing_play_sample(creatng, 41, NORMAL_PITCH, 0, 3, 0, 3, FULL_LOUDNESS); return 0; }
void meta_effect_run_unminimize (MetaWindow *window, MetaRectangle *window_rect, MetaRectangle *icon_rect, MetaEffectFinished finished, gpointer data) { MetaEffect *effect; g_return_if_fail (window != NULL); g_return_if_fail (icon_rect != NULL); effect = create_effect (META_EFFECT_UNMINIMIZE, window, finished, data); effect->u.minimize.window_rect = *window_rect; effect->u.minimize.icon_rect = *icon_rect; run_handler (effect); }
TbBool remove_workshop_object_from_player(PlayerNumber owner, ThingModel objmodel) { struct Thing *cratetng; struct Room *room; cratetng = get_workshop_box_thing(owner, objmodel); if (thing_is_invalid(cratetng)) { WARNLOG("Crate %s could not be found",object_code_name(objmodel)); return false; } room = get_room_thing_is_on(cratetng); if (room_exists(room)) { remove_workshop_object_from_workshop(room,cratetng); } else { WARNLOG("Crate thing index %d isn't placed existing room; removing anyway",(int)cratetng->index); } create_effect(&cratetng->mappos, imp_spangle_effects[cratetng->owner], cratetng->owner); destroy_object(cratetng); return true; }
void play_creature_sound_and_create_sound_thing(struct Thing *thing, long snd_idx, long a2) { struct CreatureSound *crsound; struct Thing *efftng; long i; if (playing_creature_sound(thing, snd_idx)) { return; } crsound = get_creature_sound(thing, snd_idx); if (crsound->index <= 0) { SYNCDBG(14,"No sample %d for creature %d",snd_idx,thing->model); return; } i = UNSYNC_RANDOM(crsound->count); efftng = create_effect(&thing->mappos, TngEff_Unknown49, thing->owner); if (!thing_is_invalid(efftng)) { thing_play_sample(efftng, crsound->index+i, NORMAL_PITCH, 0, 3, 0, a2, FULL_LOUDNESS); } }
long instf_pretty_path(struct Thing *creatng, long *param) { struct Dungeon *dungeon; TRACE_THING(creatng); SYNCDBG(16,"Starting"); dungeon = get_dungeon(creatng->owner); MapSlabCoord slb_x,slb_y; slb_x = subtile_slab_fast(creatng->mappos.x.stl.num); slb_y = subtile_slab_fast(creatng->mappos.y.stl.num); create_effect(&creatng->mappos, imp_spangle_effects[creatng->owner], creatng->owner); thing_play_sample(creatng, 76, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); place_slab_type_on_map(SlbT_CLAIMED, slab_subtile_center(slb_x), slab_subtile_center(slb_y), creatng->owner, 1); do_unprettying(creatng->owner, slb_x, slb_y); do_slab_efficiency_alteration(slb_x, slb_y); increase_dungeon_area(creatng->owner, 1); dungeon->lvstats.area_claimed++; remove_traps_around_subtile(slab_subtile_center(slb_x), slab_subtile_center(slb_y), NULL); return 1; }
static enum msgret message(void *obj, msg_t msg) { sprite_t *s = obj; switch(msg.type) { case MSG_UPDATE: update(s); break; case MSG_DEACTIVATE: s->flags |= SPRITE_PAUSED; s->state = DRACO_GLIDE; break; case MSG_KILL: create_effect(&explosion,s->pos); sprite_kill(s); break; default: return MSG_RET_UNKNOWN; break; } return MSG_RET_ACK; }
void CEnvAmbient::load( CInifile& ambients_config, CInifile& sound_channels_config, CInifile& effects_config, const shared_str& sect ) { m_ambients_config_filename = ambients_config.fname(); m_load_section = sect; string_path tmp; // sounds LPCSTR channels = ambients_config.r_string(sect, "sound_channels"); u32 cnt = _GetItemCount(channels); // R_ASSERT3 (cnt,"sound_channels empty", sect.c_str()); m_sound_channels.resize(cnt); for (u32 i = 0; i < cnt; ++i) m_sound_channels[i] = create_sound_channel(sound_channels_config, _GetItem(channels, i, tmp)); // effects m_effect_period.set( iFloor( ambients_config.r_float(sect, "min_effect_period")*1000.f ), iFloor( ambients_config.r_float(sect, "max_effect_period")*1000.f ) ); LPCSTR effs = ambients_config.r_string(sect, "effects"); cnt = _GetItemCount(effs); // R_ASSERT3 (cnt,"effects empty", sect.c_str()); m_effects.resize(cnt); for (u32 k = 0; k < cnt; ++k) m_effects[k] = create_effect(effects_config, _GetItem(effs, k, tmp)); R_ASSERT(!m_sound_channels.empty() || !m_effects.empty()); }
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; }
static void update(sprite_t *s) { float v[2],x,pull[2]; mech_sprite_t *ms = (mech_sprite_t *)s; sprite_get_vel(s,v); if (!(s->state & PLANE_CRASHING)) { if (s->state & PLANE_ACCELERATING) { vset(pull,mech_heading(ms)); vrot(pull,-16); /* maybe the angle should depend on up/down */ vmadd(ms->lin_impulse,engine_strength,pull); } if (s->state & PLANE_UP) ms->air_rotate = -turn_amount; else if (s->state & PLANE_DOWN) ms->air_rotate = turn_amount; else ms->air_rotate = 0; if (ms->damage >= hitpoints) { s->state |= PLANE_CRASHING; if (!(s->owner->schrodinger)){ sprite_set_animation(s,crashing[s->owner->id_in_team]); }else{ sprite_set_animation(s,crashing[MAXPLAYERINTEAMS]); } s->owner->lastEnnemi->points+=crash_point; create_effect(&fire,s->x,s->y); sprite_alarm(7000,s,SIGNAL_KILL,0); } } mech_update(ms); }
static void sigget(sprite_t *s, int signal, void *data) { float v[2] = {0,0}; sprite_t *p; float r[2]; int sigabs; switch(signal) { case SIGNAL_CANCONTROL: *(int *)data = !(s->state & SPRITE_CRASHING); break; case SIGNAL_DAMAGE: ((mech_sprite_t *)s)->damage += *(int *)data; break; case SIGNAL_UP: s->state |= SPRITE_UP; s->state &= ~SPRITE_DOWN; break; case -SIGNAL_UP: s->state &= ~SPRITE_UP; break; case SIGNAL_DOWN: s->state |= SPRITE_DOWN; s->state &= ~SPRITE_UP; break; case -SIGNAL_DOWN: s->state &= ~SPRITE_DOWN; break; case SIGNAL_KILL: create_effect(&explosion,s->x,s->y); sprite_kill(s); break; default: break; } }
static void sigget(sprite_t *s, int signal, void *data) { float v[2] = {0,0}; sprite_t *p; float r[2]; int sigabs; switch(signal) { case SIGNAL_CANCONTROL: *(int *)data = !(s->state & PLANE_CRASHING); break; case SIGNAL_DAMAGE: ((mech_sprite_t *)s)->damage += *(int *)data; ((player_t*)s->owner)->damage=(100*((mech_sprite_t *)s)->damage)/hitpoints; break; case SIGNAL_LAST_ENNEMI: ((player_t*)s->owner)->lastEnnemi=(player_t*)data; break; case SIGNAL_ACCELERATE: s->state |= PLANE_ACCELERATING; break; case -SIGNAL_ACCELERATE: s->state &= ~PLANE_ACCELERATING; break; case SIGNAL_UP: s->state |= PLANE_UP; s->state &= ~PLANE_DOWN; break; case -SIGNAL_UP: s->state &= ~PLANE_UP; break; case SIGNAL_DOWN: s->state |= PLANE_DOWN; s->state &= ~PLANE_UP; break; case -SIGNAL_DOWN: s->state &= ~PLANE_DOWN; break; case SIGNAL_FIRE: /* create bullet */ if (sprite_timer_finished(((struct biplane*)s)->gun_timer) && !(s->state & PLANE_CRASHING)) { sound_effect(&sound_gunfire,s->x,s->y); p = sprite_create(((struct biplane*)s)->bullet_type,s->owner); //p->owner=s->owner; sprite_group_insert(bullet_group,p); r[0] = mech_heading((mech_sprite_t *)s)[0]; r[1] = mech_heading((mech_sprite_t *)s)[1]; vmul(r,21); /* Find start of bullet in clumsy way */ vrot(r,-9); sprite_set_pos(p,s->x + r[0],s->y + r[1]); sprite_get_vel(s,v); vmadd(v,200,mech_heading((mech_sprite_t *)s)); sprite_set_vel(p,v); /* cannot fire again in some time */ sprite_timer_set(&(((struct biplane*)s)->gun_timer),bullet_delay); } break; case SIGNAL_NUM0: /* create bomb */ if (sprite_timer_finished(((struct biplane*)s)->bomb_timer) && (!(s->state & PLANE_CRASHING)) && (((struct biplane*)s)->nr_bombs > 0)) { ((struct biplane*)s)->nr_bombs--; p = sprite_create(&bomb,s->owner); p->anim_p = s->anim_p; ((mech_sprite_t *)p)->angle = ((mech_sprite_t *)s)->angle; r[0] = mech_heading((mech_sprite_t *)s)[0]; r[1] = mech_heading((mech_sprite_t *)s)[1]; vmul(r,14); vrot(r,-80); sprite_set_pos(p,s->x + r[0],s->y + r[1]); sprite_get_vel(s,v); vmadd(v,5,r); sprite_set_vel(p,v); sprite_group_insert(bomb_group,p); sprite_timer_set(&(((struct biplane*)s)->bomb_timer), bomb_delay); } break; case SIGNAL_NUM1: /* jump ship */ if (sprite_timer_finished(((struct biplane*)s)->bomb_timer) && (!(s->state & PLANE_CRASHING))) { p = sprite_create(¶chute,NULL); r[0] = mech_heading((mech_sprite_t *)s)[0]; r[1] = mech_heading((mech_sprite_t *)s)[1]; vmul(r,14); vrot(r,80); sprite_set_pos(p,s->x + r[0],s->y + r[1]); sprite_get_vel(s,v); vmadd(v,5,r); sprite_set_vel(p,v); sprite_group_insert(mech_group,p); sprite_timer_set(&(((struct biplane*)s)->bomb_timer),bomb_delay); } break; case SIGNAL_KILL: create_effect(&explosion,s->x,s->y); sprite_kill(s); break; case SIGNAL_ISHARMLESS: if (s->state & PLANE_CRASHING) ((struct signal_reply *)data)->reply = 1; break; case SIGNAL_STATSTRING://TTODO : useless ? sprintf(data,"%i bombs",((struct biplane*)s)->nr_bombs); break; default: break; } }
short researching(struct Thing *thing) { struct Dungeon *dungeon; long i; TRACE_THING(thing); dungeon = get_dungeon(thing->owner); if (is_neutral_thing(thing)) { ERRORLOG("Neutral %s index %d cannot do research",thing_model_name(thing),(int)thing->index); remove_creature_from_work_room(thing); set_start_state(thing); return CrStRet_Unchanged; } if (!creature_can_do_research(thing)) { if (!is_neutral_thing(thing) && (dungeon->current_research_idx < 0)) { if (is_my_player_number(dungeon->owner)) output_message(SMsg_NoMoreReseach, 500, true); } remove_creature_from_work_room(thing); set_start_state(thing); return CrStRet_Unchanged; } // Get and verify working room struct Room *room; room = get_room_thing_is_on(thing); if (creature_work_in_room_no_longer_possible(room, RoK_LIBRARY, thing)) { remove_creature_from_work_room(thing); set_start_state(thing); return CrStRet_ResetFail; } if (room->used_capacity > room->total_capacity) { output_message_room_related_from_computer_or_player_action(room->owner, room->kind, OMsg_RoomTooSmall); remove_creature_from_work_room(thing); set_start_state(thing); return CrStRet_ResetOk; } process_research_function(thing); struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(thing); if ( (game.play_gameturn - dungeon->field_AE5 < 50) && ((game.play_gameturn + thing->index) & 0x03) == 0) { external_set_thing_state(thing, CrSt_CreatureBeHappy); cctrl->countdown_282 = 50; cctrl->long_9A = 0; return CrStRet_Modified; } if (cctrl->instance_id != CrInst_NULL) return 1; cctrl->field_82++; // Shall we do some "Standing and thinking" if (cctrl->field_82 <= 128) { if (cctrl->byte_9A == 3) { // Do some random thinking if ((cctrl->field_82 % 16) == 0) { i = ACTION_RANDOM(LbFPMath_PI) - LbFPMath_PI/2; cctrl->long_9B = ((long)thing->move_angle_xy + i) & LbFPMath_AngleMask; cctrl->byte_9A = 4; } } else { // Look at different direction while thinking if (creature_turn_to_face_angle(thing, cctrl->long_9B) < LbFPMath_PI/18) { cctrl->byte_9A = 3; } } return 1; } // Finished "Standing and thinking" - make "new idea" effect and go to next position if (!setup_random_head_for_room(thing, room, NavRtF_Default)) { ERRORLOG("Cannot move %s index %d in %s room", thing_model_name(thing),(int)thing->index,room_code_name(room->kind)); set_start_state(thing); return 1; } thing->continue_state = CrSt_Researching; cctrl->field_82 = 0; cctrl->byte_9A = 3; if (cctrl->explevel < 3) { create_effect(&thing->mappos, TngEff_Unknown54, thing->owner); } else if (cctrl->explevel < 6) { create_effect(&thing->mappos, TngEff_Unknown55, thing->owner); } else { create_effect(&thing->mappos, TngEff_Unknown56, thing->owner); } return 1; }
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; }
long instf_dig(struct Thing *creatng, long *param) { struct CreatureControl *cctrl; struct Dungeon *dungeon; struct SlabMap *slb; long stl_x,stl_y; long task_idx,taskkind; long dig_damage,gold; SYNCDBG(16,"Starting"); TRACE_THING(creatng); //return _DK_instf_dig(thing, param); cctrl = creature_control_get_from_thing(creatng); dungeon = get_dungeon(creatng->owner); task_idx = cctrl->word_91; { struct MapTask *task; task = get_dungeon_task_list_entry(dungeon,task_idx); taskkind = task->kind; if (task->coords != cctrl->word_8F) { return 0; } stl_x = stl_num_decode_x(cctrl->word_8F); stl_y = stl_num_decode_y(cctrl->word_8F); } slb = get_slabmap_for_subtile(stl_x, stl_y); if (slabmap_block_invalid(slb)) { return 0; } dig_damage = calculate_damage_did_to_slab_with_single_hit(creatng, slb); if (slb->health > dig_damage) { if (!slab_kind_is_indestructible(slb->kind)) slb->health -= dig_damage; thing_play_sample(creatng, 63 + UNSYNC_RANDOM(6), NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS); create_effect(&creatng->mappos, TngEff_Unknown25, creatng->owner); if (taskkind == SDDigTask_MineGold) { gold = calculate_gold_digged_out_of_slab_with_single_hit(dig_damage, creatng->owner, cctrl->explevel, slb); creatng->creature.gold_carried += gold; dungeon->lvstats.gold_mined += gold; } return 0; } // slb->health <= dig_damage - we're going to destroy the slab remove_from_task_list(creatng->owner, task_idx); if (taskkind == SDDigTask_MineGold) { gold = calculate_gold_digged_out_of_slab_with_single_hit(slb->health, creatng->owner, cctrl->explevel, slb); creatng->creature.gold_carried += gold; dungeon->lvstats.gold_mined += gold; mine_out_block(stl_x, stl_y, creatng->owner); if (dig_has_revealed_area(stl_x, stl_y, creatng->owner)) { EventIndex evidx; evidx = event_create_event_or_update_nearby_existing_event( subtile_coord_center(stl_x), subtile_coord_center(stl_y), EvKind_AreaDiscovered, creatng->owner, 0); if ((evidx > 0) && is_my_player_number(creatng->owner)) output_message(SMsg_DugIntoNewArea, 0, true); } } else if (taskkind == SDDigTask_DigEarth) { dig_out_block(stl_x, stl_y, creatng->owner); if (dig_has_revealed_area(stl_x, stl_y, creatng->owner)) { EventIndex evidx; evidx = event_create_event_or_update_nearby_existing_event( subtile_coord_center(stl_x), subtile_coord_center(stl_y), EvKind_AreaDiscovered, creatng->owner, 0); if ((evidx > 0) && is_my_player_number(creatng->owner)) output_message(SMsg_DugIntoNewArea, 0, true); } } check_map_explored(creatng, stl_x, stl_y); thing_play_sample(creatng, 72 + UNSYNC_RANDOM(3), NORMAL_PITCH, 0, 3, 0, 4, FULL_LOUDNESS); return 1; }