Пример #1
0
TbBool attempt_anger_job_join_enemy(struct Thing *creatng)
{
    struct Thing *heartng;
    int i, n;
    n = ACTION_RANDOM(PLAYERS_COUNT);
    for (i=0; i < PLAYERS_COUNT; i++, n=(n+1)%PLAYERS_COUNT)
    {
        if ((n == game.neutral_player_num) || (n == creatng->owner))
            continue;
        struct PlayerInfo *player;
        player = get_player(n);
        if (!player_exists(player) || (player->field_2C != 1))
            continue;
        heartng = get_player_soul_container(n);
        if (thing_exists(heartng) && (heartng->active_state != 3))
        {
            TRACE_THING(heartng);
            if (creature_can_navigate_to(creatng, &heartng->mappos, NavRtF_Default)) {
                change_creature_owner(creatng, n);
                anger_set_creature_anger_all_types(creatng, 0);
            }
        }
    }
    return false;
}
Пример #2
0
TbBool good_setup_wander_to_dungeon_heart(struct Thing *creatng, PlayerNumber plyr_idx)
{
    struct PlayerInfo *player;
    SYNCDBG(18,"Starting");
    TRACE_THING(creatng);
    if (creatng->owner == plyr_idx)
    {
        ERRORLOG("The %s tried to wander to own (%d) heart", thing_model_name(creatng), (int)plyr_idx);
        return false;
    }
    player = get_player(plyr_idx);
    if (!player_exists(player))
    {
        WARNLOG("The %s tried to wander to inactive player (%d) heart", thing_model_name(creatng), (int)plyr_idx);
        return false;
    }
    struct Thing *heartng;
    heartng = get_player_soul_container(plyr_idx);
    TRACE_THING(heartng);
    if (thing_is_invalid(heartng))
    {
        WARNLOG("The %s tried to wander to player %d which has no heart", thing_model_name(creatng), (int)plyr_idx);
        return false;
    }
    set_creature_object_combat(creatng, heartng);
    return true;
}
Пример #3
0
long computer_check_no_imps(struct Computer2 *comp, struct ComputerCheck * check)
{
    struct Dungeon *dungeon;
    SYNCDBG(8,"Starting");
    //return _DK_computer_check_no_imps(comp, check);
    dungeon = comp->dungeon;
    if (dungeon->num_active_diggers >= check->param1) {
        return 4;
    }
    long able;
    able = computer_able_to_use_magic(comp, PwrK_MKDIGGER, 0, 1);
    if (able == 1)
    {
        struct Thing *heartng;
        MapSubtlCoord stl_x, stl_y;
        heartng = get_player_soul_container(dungeon->owner);
        stl_x = heartng->mappos.x.stl.num;
        stl_y = heartng->mappos.y.stl.num;
        if (xy_walkable(stl_x, stl_y, dungeon->owner))
        {
            if (try_game_action(comp, dungeon->owner, GA_UseMkDigger, 0, stl_x, stl_y, 1, 1) > Lb_OK) {
                able = 1;
            }
        }
    }
    return able;
}
Пример #4
0
void process_armageddon(void)
{
    struct PlayerInfo *player;
    struct Dungeon *dungeon;
    struct Thing *heartng;
    long i;
    SYNCDBG(6,"Starting");
    //_DK_process_armageddon(); return;
    if (game.armageddon_cast_turn == 0)
        return;
    if (game.armageddon.count_down+game.armageddon_cast_turn > game.play_gameturn)
    {
        if (player_cannot_win(game.armageddon_caster_idx))
        {
            // Stop the armageddon if its originator is just losing
            game.armageddon_cast_turn = 0;
        }
    } else
    if (game.armageddon.count_down+game.armageddon_cast_turn == game.play_gameturn)
    {
        for (i=0; i < PLAYERS_COUNT; i++)
        {
            player = get_player(i);
            if (player_exists(player))
            {
              if (player->field_2C == 1)
                reveal_whole_map(player);
            }
        }
    } else
    if (game.armageddon.count_down+game.armageddon_cast_turn < game.play_gameturn)
    {
        for (i=0; i < PLAYERS_COUNT; i++)
        {
            player = get_player(i);
            if ( (player_exists(player)) && (player->field_2C == 1) )
            {
                dungeon = get_dungeon(player->id_number);
                if ((player->victory_state == VicS_Undecided) && (dungeon->num_active_creatrs == 0))
                {
                    event_kill_all_players_events(i);
                    set_player_as_lost_level(player);
                    if (is_my_player_number(i))
                        LbPaletteSet(engine_palette);
                    heartng = get_player_soul_container(player->id_number);
                    if (thing_exists(heartng)) {
                        heartng->health = -1;
                    }
                }
            }
        }
    }
}
Пример #5
0
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;
}
Пример #6
0
TbBool good_can_move_to_dungeon_heart(struct Thing *creatng, PlayerNumber plyr_idx)
{
    struct PlayerInfo *player;
    SYNCDBG(18,"Starting");
    TRACE_THING(creatng);
    player = get_player(plyr_idx);
    if (!player_exists(player))
    {
        SYNCDBG(3,"The %s cannot move to inactive player %d heart", thing_model_name(creatng), (int)plyr_idx);
        return false;
    }
    struct Thing *heartng;
    heartng = get_player_soul_container(plyr_idx);
    TRACE_THING(heartng);
    if (thing_is_invalid(heartng))
    {
        SYNCDBG(3,"The %s cannot move to player %d which has no heart", thing_model_name(creatng), (int)plyr_idx);
        return false;
    }
    return creature_can_navigate_to(creatng, &heartng->mappos, NavRtF_Default);
}
Пример #7
0
short good_returns_to_start(struct Thing *thing)
{
    struct Thing *heartng;
    // Debug code to find incorrect states
    SYNCDBG(7,"Starting");
    if (!is_hero_thing(thing))
    {
        ERRORLOG("Non hero thing %ld, %s, owner %ld - reset",(long)thing->index,thing_model_name(thing),(long)thing->owner);
        set_start_state(thing);
        erstat_inc(ESE_BadCreatrState);
        return 0;
    }
    //return _DK_good_returns_to_start(thing);
    heartng = get_player_soul_container(thing->owner);
    TRACE_THING(heartng);
    //TODO CREATURE_AI Heroes don't usually have hearts; maybe they should also go back to hero gates, or any room?
    if (!setup_person_move_to_coord(thing, &heartng->mappos, NavRtF_Default))
    {
        return 0;
    }
    thing->continue_state = CrSt_GoodBackAtStart;
    return 1;
}
Пример #8
0
/**
 * Returns if a creature can get to given players dungeon.
 * @param thing
 * @param plyr_idx
 * @return
 * @see creature_can_get_to_any_of_players_rooms() is a function used in similar manner.
 */
TbBool creature_can_get_to_dungeon(struct Thing *creatng, PlayerNumber plyr_idx)
{
    struct PlayerInfo *player;
    struct Thing *heartng;
    SYNCDBG(18,"Starting");
    player = get_player(plyr_idx);
    if (!player_exists(player) || (player->field_2C != 1))
    {
        SYNCDBG(18,"The %s index %d cannot get to inactive player %d",thing_model_name(creatng),(int)creatng->index,(int)plyr_idx);
        return false;
    }
    heartng = get_player_soul_container(player->id_number);
    if (thing_is_invalid(heartng))
    {
        SYNCDBG(18,"The %s index %d cannot get to player %d without heart",thing_model_name(creatng),(int)creatng->index,(int)plyr_idx);
        return false;
    }
    if (heartng->active_state == ObSt_BeingDestroyed)
    {
        SYNCDBG(18,"The %s index %d cannot get to player %d due to heart state",thing_model_name(creatng),(int)creatng->index,(int)plyr_idx);
        return false;
    }
    return creature_can_navigate_to(creatng, &heartng->mappos, NavRtF_Default);
}
Пример #9
0
TbBool player_has_heart(PlayerNumber plyr_idx)
{
    return thing_exists(get_player_soul_container(plyr_idx));
}
Пример #10
0
/**
 * Checks if a computer player has not enough imps.
 * @param comp
 * @param check The check structure; param1 is preferred amount of imps, param2 is minimal amount.
 */
long computer_check_no_imps(struct Computer2 *comp, struct ComputerCheck * check)
{
	if (is_newdig_enabled(comp))
	{
		//workaround for interval seeming to be ignored by from my reconfiguration.
		//modern computers can handle interval 1 and interval 200 is awfully passive and easy to kill
		//interval 20 means player-like imp swarms will form while not being excessive
		//consider making configurable again if *properly* reconfiguring to 20 for all levels except easy beginner levels

		if (check->turns_interval > 20)
			check->turns_interval = 20;
		if (check->param2 < 8)
			check->param2 = 8;
	}

    struct Dungeon *dungeon;
    SYNCDBG(8,"Starting");
    dungeon = comp->dungeon;
    if (dungeon_invalid(dungeon) || !player_has_heart(dungeon->owner)) {
        SYNCDBG(7,"Computer players %d dungeon in invalid or has no heart",(int)dungeon->owner);
        return CTaskRet_Unk4;
    }

	long power_price, lowest_price;
	TbBool diggers_are_cheap;
	power_price = compute_power_price(dungeon->owner, PwrK_MKDIGGER, 0);
	lowest_price = compute_lowest_digger_price(dungeon->owner);
	diggers_are_cheap = power_price <= lowest_price;

	//see if we can sacrifice imps to reduce price
	if (gameadd.sacrifice_info.classic_imp_sacrifice)
	{
		SYNCDBG(18, "Imp creation power price: %d, lowest: %d", power_price, lowest_price);

		if (!diggers_are_cheap
			&& dungeon->total_money_owned > power_price //TODO: might need to multiply for safety factor
			&& dungeon_has_room(dungeon, RoK_TEMPLE))
		{
			struct Thing* imp;
			imp = find_imp_for_sacrifice(comp->dungeon);
			if (!thing_is_invalid(imp))
			{
				long dist;
				struct Room* room;
				room = find_room_nearest_to_position(dungeon->owner, RoK_TEMPLE, &imp->mappos, &dist);
				if (!room_is_invalid(room))
				{
					if (create_task_move_creature_to_subtile(comp, imp, room->central_stl_x, room->central_stl_y, CrSt_CreatureSacrifice))
						return CTaskRet_Unk4;
				}
			}
		}
	}

	//regular old imp check after this point
    long controlled_diggers;
	TbBool digging_gems;
	long limit;
	digging_gems = is_digging_any_gems(dungeon);
    controlled_diggers = dungeon->num_active_diggers - count_player_diggers_not_counting_to_total(dungeon->owner);
	//SYNCLOG("controlled diggers of %d = %d, params = %d %d", (int)dungeon->owner, controlled_diggers, check->param1, check->param2);
	limit = check->param1;
	if (digging_gems)
	{
		if (diggers_are_cheap)
			limit = max(limit, 50);
		else
			limit = max(limit, 20);
	}
    if (controlled_diggers >= limit) {
        return CTaskRet_Unk4;
    }
    long able;
	if ((controlled_diggers == 0 || (controlled_diggers < 3 && (digging_gems || diggers_are_cheap))) && is_power_available(dungeon->owner, PwrK_MKDIGGER))
	{
		//ignore payday and everything else, we need at least 3 imp to play the game
		able = dungeon->total_money_owned >= compute_power_price(dungeon->owner, PwrK_MKDIGGER, 0);
		//TODO: recovery could be improved further by looking at length to payday and time it takes to get more money to increase lower bound
	} else if (controlled_diggers >= check->param2 && !digging_gems) {
        // We have less than preferred amount, but higher than minimal; allow building if we've got spare money
        able = computer_able_to_use_magic(comp, PwrK_MKDIGGER, 0, 3 + (controlled_diggers - check->param2)/4);
    } else {
        able = computer_able_to_use_magic(comp, PwrK_MKDIGGER, 0, 1);
    }
    if (able == CTaskRet_Unk1)
    {
        struct Thing *heartng;
        MapSubtlCoord stl_x, stl_y;
        heartng = get_player_soul_container(dungeon->owner);
        stl_x = heartng->mappos.x.stl.num;
        stl_y = heartng->mappos.y.stl.num;
        if (xy_walkable(stl_x, stl_y, dungeon->owner))
        {
            if (try_game_action(comp, dungeon->owner, GA_UseMkDigger, 0, stl_x, stl_y, 1, 1) > Lb_OK) {
                return CTaskRet_Unk1;
            }
        }
        return CTaskRet_Unk1;
    }
    return CTaskRet_Unk0;
}