Example #1
0
	const player_info* get_player_info() const { return is_human(); }
Example #2
0
File: team.hpp Project: CIB/wesnoth
	bool is_local() const { return is_human() || is_ai() || is_idle(); }
Example #3
0
struct monst *
tamedog(struct monst *mtmp, struct obj *obj)
{
    struct monst *mtmp2;

    /* The Wiz, Medusa and the quest nemeses aren't even made peaceful. */
    if (mtmp->iswiz || mtmp->data == &mons[PM_MEDUSA]
        || (mtmp->data->mflags3 & M3_WANTSARTI))
        return NULL;

    /* worst case, at least it'll be peaceful; this uses the main RNG because
       realtime effects means that this won't really sync anyway; this also
       calls set_malign (thus there's no need for the caller to call it after
       calling tamedog()) */
    msethostility(mtmp, FALSE, TRUE);
    if (flags.moonphase == FULL_MOON && night() && rn2(6) && obj &&
        mtmp->data->mlet == S_DOG)
        return NULL;

    /* If we cannot tame it, at least it's no longer afraid. */
    mtmp->mflee = 0;
    mtmp->mfleetim = 0;

    /* make grabber let go now, whether it becomes tame or not */
    if (mtmp == u.ustuck) {
        if (Engulfed)
            expels(mtmp, mtmp->data, TRUE);
        else if (!(Upolyd && sticks(youmonst.data)))
            unstuck(mtmp);
    }

    /* feeding it treats makes it tamer */
    if (mtmp->mtame && obj) {
        int tasty;

        if (mtmp->mcanmove && !mtmp->mconf && !mtmp->meating &&
            ((tasty = dogfood(mtmp, obj)) == DOGFOOD ||
             (tasty <= ACCFOOD && CONST_EDOG(mtmp)->hungrytime <= moves))) {
            /* pet will "catch" and eat this thrown food */
            if (canseemon(mtmp)) {
                boolean big_corpse = (obj->otyp == CORPSE &&
                                      obj->corpsenm >= LOW_PM &&
                                      mons[obj->corpsenm].msize >
                                      mtmp->data->msize);
                pline("%s catches %s%s", Monnam(mtmp), the(xname(obj)),
                      !big_corpse ? "." : ", or vice versa!");
            } else if (cansee(mtmp->mx, mtmp->my))
                pline("%s.", Tobjnam(obj, "stop"));
            /* dog_eat expects a floor object */
            place_object(obj, level, mtmp->mx, mtmp->my);
            dog_eat(mtmp, obj, mtmp->mx, mtmp->my, FALSE);
            /* eating might have killed it, but that doesn't matter here; a
               non-null result suppresses "miss" message for thrown food and
               also implies that the object has been deleted */
            return mtmp;
        } else
            return NULL;
    }

    if (mtmp->mtame || !mtmp->mcanmove ||
        /* monsters with conflicting structures cannot be tamed */
        mtmp->isshk || mtmp->isgd || mtmp->ispriest || mtmp->isminion ||
        is_covetous(mtmp->data) || is_human(mtmp->data) ||
        (is_demon(mtmp->data) && !is_demon(youmonst.data)) ||
        (obj && dogfood(mtmp, obj) >= MANFOOD))
        return NULL;

    if (mtmp->m_id == u.quest_status.leader_m_id)
        return NULL;

    /* make a new monster which has the pet extension */
    mtmp2 = newmonst(MX_EDOG, mtmp->mnamelth);
    *mtmp2 = *mtmp;
    mtmp2->mxtyp = MX_EDOG;
    mtmp2->mxlth = sizeof (struct edog);
    if (mtmp->mnamelth)
        strcpy(NAME_MUTABLE(mtmp2), NAME(mtmp));
    initedog(mtmp2);
    replmon(mtmp, mtmp2);
    /* `mtmp' is now obsolete */

    if (obj) {  /* thrown food */
        /* defer eating until the edog extension has been set up */
        place_object(obj, level, mtmp2->mx, mtmp2->my); /* put on floor */
        /* devour the food (might grow into larger, genocided monster) */
        if (dog_eat(mtmp2, obj, mtmp2->mx, mtmp2->my, TRUE) == 2)
            return mtmp2;       /* oops, it died... */
        /* `obj' is now obsolete */
    }

    if (mtmp2->dlevel == level)
        newsym(mtmp2->mx, mtmp2->my);
    if (attacktype(mtmp2->data, AT_WEAP)) {
        mtmp2->weapon_check = NEED_HTH_WEAPON;
        mon_wield_item(mtmp2);
    }
    return mtmp2;
}
Example #4
0
	player_info* get_player_info() { return is_human(); }
Example #5
0
/* fungi will eat even tainted food */
int
dogfood(const struct monst *mon, struct obj *obj)
{
    boolean carni = carnivorous(mon->data);
    boolean herbi = herbivorous(mon->data);
    const struct permonst *fptr = &mons[obj->corpsenm];
    boolean starving;

    if (is_quest_artifact(obj) || obj_resists(obj, 0, 95))
        return obj->cursed ? TABU : APPORT;

    switch (obj->oclass) {
    case FOOD_CLASS:
        if (obj->otyp == CORPSE &&
            ((touch_petrifies(&mons[obj->corpsenm]) && !resists_ston(mon))
             || is_rider(fptr)))
            return TABU;

        /* Ghouls only eat old corpses... yum! */
        if (mon->data == &mons[PM_GHOUL])
            return (obj->otyp == CORPSE &&
                    peek_at_iced_corpse_age(obj) + 50L <=
                    moves) ? DOGFOOD : TABU;

        if (!carni && !herbi)
            return obj->cursed ? UNDEF : APPORT;

        /* a starving pet will eat almost anything */
        starving = (mon->mtame && !mon->isminion &&
                    CONST_EDOG(mon)->mhpmax_penalty);

        switch (obj->otyp) {
        case TRIPE_RATION:
        case MEATBALL:
        case MEAT_RING:
        case MEAT_STICK:
        case HUGE_CHUNK_OF_MEAT:
            return carni ? DOGFOOD : MANFOOD;
        case EGG:
            if (touch_petrifies(&mons[obj->corpsenm]) && !resists_ston(mon))
                return POISON;
            return carni ? CADAVER : MANFOOD;
        case CORPSE:
            if ((peek_at_iced_corpse_age(obj) + 50L <= moves &&
                 obj->corpsenm != PM_LIZARD && obj->corpsenm != PM_LICHEN &&
                 mon->data->mlet != S_FUNGUS) ||
                (acidic(&mons[obj->corpsenm]) && !resists_acid(mon)) ||
                (poisonous(&mons[obj->corpsenm]) && !resists_poison(mon)))
                return POISON;
            else if (vegan(fptr))
                return herbi ? CADAVER : MANFOOD;
            else
                return carni ? CADAVER : MANFOOD;
        case CLOVE_OF_GARLIC:
            return (is_undead(mon->data) ? TABU
                    : ((herbi || starving) ? ACCFOOD : MANFOOD));
        case TIN:
            return metallivorous(mon->data) ? ACCFOOD : MANFOOD;
        case APPLE:
        case CARROT:
            return herbi ? DOGFOOD : starving ? ACCFOOD : MANFOOD;
        case BANANA:
            return ((mon->data->mlet ==
                     S_YETI) ? DOGFOOD : ((herbi ||
                                           starving) ? ACCFOOD : MANFOOD));

        case K_RATION:
        case C_RATION:
        case CRAM_RATION:
        case LEMBAS_WAFER:
        case FOOD_RATION:
            if (is_human(mon->data) || is_elf(mon->data) || is_dwarf(mon->data)
                || is_gnome(mon->data) || is_orc(mon->data))
                return ACCFOOD;

        default:
            if (starving)
                return ACCFOOD;
            return (obj->otyp >
                    SLIME_MOLD ? (carni ? ACCFOOD : MANFOOD) :
                    (herbi ? ACCFOOD : MANFOOD));
        }
    default:
        if (obj->otyp == AMULET_OF_STRANGULATION ||
            obj->otyp == RIN_SLOW_DIGESTION)
            return TABU;
        if (hates_silver(mon->data) && objects[obj->otyp].oc_material == SILVER)
            return TABU;
        if (mon->data == &mons[PM_GELATINOUS_CUBE] && is_organic(obj))
            return ACCFOOD;
        if (metallivorous(mon->data) && is_metallic(obj) &&
            (is_rustprone(obj) || mon->data != &mons[PM_RUST_MONSTER])) {
            /* Non-rustproofed ferrous based metals are preferred. */
            return (is_rustprone(obj) && !obj->oerodeproof) ? DOGFOOD : ACCFOOD;
        }
        if (!obj->cursed && obj->oclass != BALL_CLASS &&
            obj->oclass != CHAIN_CLASS)
            return APPORT;
        /* fall into next case */
    case ROCK_CLASS:
        return UNDEF;
    }
}
Example #6
0
//--------- Begin of function Unit::init ---------//
//
// <int> unitId               - the id. of the unit
// <int> nationRecno          - the recno of nation
// [int] rankId               - rank id. of the unit (none for non-human unit)
// [int] unitLoyalty          - loyalty of the unit  (none for non-human unit)
// [int] startXLoc, startYLoc - the starting location of the unit
//                              (if startXLoc < 0, this is a unit for hire, and is not a unit of the game yet. init_sprite() won't be called for this unit)
//                              (default: -1, -1)
//
// Note: sprite_recno must be initialized first before calling Unit::init()
//
void Unit::init(int unitId, int nationRecno, int rankId, int unitLoyalty, int startXLoc, int startYLoc)
{
	//------------ set basic vars -------------//

	nation_recno  = (char) nationRecno;
	rank_id       = rankId;       // rank_id must be initialized before init_unit_id() as init_unit_id() may overwrite it

	if( rank_id == RANK_GENERAL || rank_id == RANK_KING )
	{
		err_when( team_info );
		team_info = (TeamInfo*) mem_add( sizeof(TeamInfo) );
		memset( team_info, 0, sizeof(TeamInfo) );
	}

	init_unit_id(unitId);

	race_id = (char) unit_res[unit_id]->race_id;

	//------- init unit name ---------//

	if( is_human() && unit_id != UNIT_WAGON )
	{
		name_id = race_res[race_id]->get_new_name_id();
	}
	else if( is_monster() )
	{
		name_id = monster_res.get_new_name_id();
	}
	else  //---- init non-human unit series no. ----//
	{
		if( nation_recno )
			name_id = ++nation_array[nation_recno]->last_unit_name_id_array[unit_id-1];
		else
			name_id = 0;
	}

	// ###### begin Gilbert 23/2 ######//
	unique_id = misc.rand_long();
	// ###### end Gilbert 23/2 ######//

	//---------- init other vars ----------//

	err_when( unitLoyalty < 0 || unitLoyalty > 100 );

	loyalty = unitLoyalty;

	// ##### begin Gilbert 29/5 ########//
	if( is_die_after_attack() )
		// behavior_mode = UNIT_STAND_GROUND;		// bee die after attack, so don't waste his life
		behavior_mode = UNIT_DEFENSIVE;		// bee die after attack, so don't waste his life
	else
		behavior_mode = UNIT_AGGRESSIVE;		// the default mode is aggressive
	// ##### end Gilbert 29/5 ########//

	//--------- init skill, and skill potential ---------//

	skill.init(unit_id, 100);
	set_combat_level(-1);

	hit_points = (float) max_hit_points();

	//------ initialize the base Sprite class -------//

	if( startXLoc >= 0 )
		init_sprite( startXLoc, startYLoc );
	else
		cur_x = -1;

	//-------------- update loyalty -------------//

	update_loyalty();

	//--------------- init AI info -------------//

	init_ai();

	//----------- init derived class ----------//

	init_derived();

	set_combat_level(-1);
}
Example #7
0
//--------- Begin of function Unit::deinit ---------//
//
void Unit::deinit()
{
	//---------- free up team_info ----------//

	if( team_info )
	{
		mem_del(team_info);
		team_info = NULL;
	}

	//---------------------------------------//

	// ####### begin Gilbert 22/3 ########//
	if( sys.quick_exit_flag() )
	{
		if( game.is_campaign_mode() )
		{
			// if in campaign mode, free name before exit

			if( name_id )
			{
				if( is_human() && unit_id != UNIT_WAGON )
				{
					if( name_id )
						race_res[race_id]->free_name_id( name_id );
				}
				else if( is_monster() )
				{
					if( name_id )
						monster_res.free_name_id( name_id );
				}
				else  //---- init non-human unit series no. ----//
				{
				}

				name_id = 0;
			}
		}
		return;
	}
	// ####### end Gilbert 22/3 ########//

	//---------------------------------------//

	err_when( unit_array.is_truly_deleted(sprite_recno) );

	if( !unit_id )
		return;

	// ######### begin Gilbert 23/2 #######//
	// -------- update win/lose condition or die -------//

	if( hit_points <= 0.0f || cur_action == SPRITE_DIE )
	{
		game.update_condition_on_killed( unique_id );
	}
	// ######### end Gilbert 23/2 #######//

	//--------- drop item -----------//

	if( !sys.signal_exit_flag && item.id )
	{
		drop_item(COMMAND_AUTO);
	}

	//-------- if this is a king --------//

	if( !sys.signal_exit_flag && nation_recno )
	{
		if( rank_id == RANK_KING )    // check nation_recno because monster kings will die also.
		{
			king_die();
			err_when( unit_array.is_truly_deleted(sprite_recno) );
		}
		else if( rank_id == RANK_GENERAL )
		{
			general_die();
			err_when( unit_array.is_truly_deleted(sprite_recno) );
		}
	}

	// ####### begin Gilbert 12/3 #######//

	// -------- free name id after general_die, which reads name_id ---------//

	if( name_id )
	{
		if( is_human() && unit_id != UNIT_WAGON )
		{
			if( name_id )
				race_res[race_id]->free_name_id( name_id );
		}
		else if( is_monster() )
		{
			if( name_id )
				monster_res.free_name_id( name_id );
		}
		else  //---- init non-human unit series no. ----//
		{
		}

		name_id = 0;
	}

	// ####### end Gilbert 12/3 #######//

	//---- if this is a general, deinit its link with its soldiers ----//
   //
   // We do not use team_info because monsters and rebels also use
	// leader_unit_recno and they do not use keep the member info
   // in team_info.
   //
   //-----------------------------------------------------------------//

   if( rank_id == RANK_GENERAL || rank_id == RANK_KING )
	{
		for( int i=unit_array.size() ; i>0 ; i-- )
      {
         if( unit_array.is_deleted(i) )
            continue;

			if( unit_array[i]->leader_unit_recno == sprite_recno )
				unit_array[i]->leader_unit_recno = 0;
      }
   }

	//----- if this is a unit on a ship ------//

	if( unit_mode == UNIT_MODE_ON_SHIP )
	{
		err_here();
		/*
		if( !unit_array.is_deleted(unit_mode_para) )    // the ship may have been destroyed at the same time. Actually when the ship is destroyed, all units onboard are killed and this function is called.
		{
			Unit* unitPtr = unit_array[unit_mode_para];

			err_when( unit_res[unitPtr->unit_id]->unit_class != UNIT_CLASS_SHIP );

			((UnitMarine*)unitPtr)->del_unit(sprite_recno);
		}
		*/
	}

	//----- if this is a ship in the harbor -----//

	else if( unit_mode == UNIT_MODE_IN_HARBOR )
	{
		err_here();
		/*
		if( !firm_array.is_deleted(unit_mode_para) )    // the ship may have been destroyed at the same time. Actually when the ship is destroyed, all firms onboard are killed and this function is called.
		{
			Firm* firmPtr = firm_array[unit_mode_para];

			err_when( firmPtr->firm_id != FIRM_HARBOR );

			((FirmHarbor*)firmPtr)->del_hosted_ship(sprite_recno);
		}
		*/
	}

	//----- if this unit is a constructor in a firm -------//

	else if( unit_mode == UNIT_MODE_CONSTRUCT_FIRM )
	{
		err_when( firm_array[unit_mode_para]->builder_recno != sprite_recno );

		firm_array[unit_mode_para]->builder_recno = 0;
	}

	//----- if this unit is a constructor in a town -------//

	else if( unit_mode == UNIT_MODE_CONSTRUCT_TOWN )
	{
		err_when( town_array[unit_mode_para]->builder_recno != sprite_recno );

		town_array[unit_mode_para]->builder_recno = 0;
	}

	//-------- if this is a spy ---------//

   if( spy_recno )
   {
      spy_array.del_spy( spy_recno );
		spy_recno = 0;
   }

   //---------- reset command ----------//

   if( power.command_unit_recno == sprite_recno )
      power.reset_command();

   //-----------------------------------//

   deinit_unit_id();

	//----- if cur_x == -1, the unit has not yet been hired -----//

	if( cur_x >= 0 )
		deinit_sprite();
	// ##### patch begin Gilbert 6/10 ######//
	else if( selected_flag )	// caravan may be deinit_sprite(1) and keep selected, now unselect
	{
		int curSelected = unit_array.selected_recno == sprite_recno;		// if it is currently selected unit, reset selected_recno
		deselect();
		if( curSelected && !sys.signal_exit_flag )
			info.disp();
	}
	// ##### patch end Gilbert 6/10 ######//

	//--------------- deinit AI info -------------//

	deinit_ai();

	//-------------- reset unit_id ---------------//

	unit_id = 0;
}
Example #8
0
//--------- Begin of function Nation::think_destroy_raw_site_guard --------//
//
int Nation::think_destroy_raw_site_guard()
{
	Site* 	 sitePtr;
	Location* locPtr;
	Unit* 	 unitPtr;

	for( int i=site_array.size() ; i>0 ; i-- )
	{
		if( site_array.is_deleted(i) )
			continue;

		sitePtr = site_array[i];

		//--- if there is already a mine built on this raw site ---//

		if( sitePtr->has_mine )
			continue;

		//----- if there is a unit standing on this site -----//

		locPtr = world.get_loc( sitePtr->map_x_loc, sitePtr->map_y_loc );

		if( !locPtr->unit_recno(UNIT_LAND) )
			continue;

		unitPtr = unit_array[ locPtr->unit_recno(UNIT_LAND) ];

		if( unitPtr->cur_action != SPRITE_IDLE )		// only attack if this unit is idle
			continue;

		if( unitPtr->nation_recno == nation_recno )	// don't attack our own units
			continue;

		//------ check if we have a presence in this region ----//

		if( is_human() && base_town_count_in_region(sitePtr->region_id) == 0 )
			continue;

		//------ check the relationship with this unit ------//
		//
		// If we are friendly with this nation, don't attack it.
		//
		//---------------------------------------------------//

		if( get_relation_status(unitPtr->nation_recno) >= RELATION_FRIENDLY )
			continue;

		//--------- attack the enemy unit ---------//

		int hasWar;
		int enemyCombatLevel = mobile_defense_combat_level( sitePtr->map_x_loc,
									  sitePtr->map_y_loc, unitPtr->nation_recno, 1, hasWar );

		if( enemyCombatLevel == - 1 )		// a war is going on here, don't attack this target
			continue;

		if( ai_attack_target(sitePtr->map_x_loc, sitePtr->map_y_loc, enemyCombatLevel, 0, 0, 0, 0, 1) )		// 1-use all camps
			return 1;
	}

	return 0;
}
Example #9
0
//----- Begin of function Nation::consider_accept_surrender_request -----//
//
// Consider accepting the cash offer and sell the throne to another kingdom.
//
// talkMsg->talk_para1 - the amount offered.
//
int Nation::consider_accept_surrender_request(TalkMsg* talkMsg)
{
	Nation* nationPtr = nation_array[talkMsg->from_nation_recno];
	int    offeredAmt = talkMsg->talk_para1 * 10;			// *10 to restore its original value which has been divided by 10 to cope with <short> upper limit

	//--- if the nation does not have any towns, camps or generals, it will have a larger tendency to surrender. ---//

	int weakNation = (ai_town_count==0 && ai_camp_count==0 && ai_general_count==0);

	//---- only surrender to nations of the same nationality or Fryhtan species ----//

	if( is_human() != nationPtr->is_human() )
		return 0;

	//---- don't surrender to the player if the player is already the most powerful nation ---//

	if( !weakNation && !nationPtr->is_ai() && config.ai_aggressiveness >= OPTION_HIGH )
	{
		if( nation_array.max_overall_nation_recno == nationPtr->nation_recno )
			return 0;
	}

	//--- if we are running out of cash, ignore all normal thinking ---//

	if( !(cash < 100 && profit_365days() < 0) && !weakNation )
	{
		//----- never surrender to a weaker nation ------//

		if( nationPtr->overall_rank_rating() < overall_rank_rating() )
			return 0;

		//------ don't surrender if we are still strong -----//

		if( overall_rank_rating() > 30 + pref_peacefulness/4 )		// 30 to 55
			return 0;

		//---- don't surrender if our cash is more than the amount they offered ----//

		if( offeredAmt < cash * (75+pref_cash_reserve/2) / 100 )		// 75% to 125%
			return 0;

		//-- if there are only two nations left, don't surrender if we still have some power --//

		if( nation_array.nation_count == 2 )
		{
			if( overall_rank_rating() > 20 - 10 * pref_military_courage / 100 )
				return 0;
		}
	}

	//-------------------------------------//

	int surrenderToRating = ai_surrender_to_rating(talkMsg->from_nation_recno);

	surrenderToRating += 100 * offeredAmt / 10000;

	int acceptRating = overall_rank_rating()*13 + 100;

	//------ AI aggressiveness effects -------//

	switch( config.ai_aggressiveness )
	{
		case OPTION_HIGH:
			if( nationPtr->is_ai() )		// tend to accept AI kingdom offer easier
				acceptRating -= 75;
			else
				acceptRating += 75;
			break;

		case OPTION_VERY_HIGH:
			if( nationPtr->is_ai() )		// tend to accept AI kingdom offer easier
				acceptRating -= 150;
			else
				acceptRating += 150;
			break;
	}

	return surrenderToRating > acceptRating;
}