예제 #1
0
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);
	}
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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);
}
예제 #5
0
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;
}
예제 #6
0
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);
}
예제 #7
0
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);
    }
  }
}
예제 #8
0
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;
    }
}
예제 #9
0
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);
        }
    }
}
예제 #10
0
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));
    }
}
예제 #11
0
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;
}
예제 #12
0
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;
}
예제 #13
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);
}
예제 #14
0
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;
}
예제 #15
0
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);
    }
}
예제 #16
0
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;
}
예제 #17
0
파일: draco.c 프로젝트: uekstrom/airstrike
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;
}
예제 #18
0
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());
}
예제 #19
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;
}
예제 #20
0
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);
}
예제 #21
0
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;
    }
}
예제 #22
0
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(&parachute,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;
	}
}
예제 #23
0
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;
}
예제 #24
0
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;
}
예제 #25
0
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;
}