CHARACTER_RANK_VALUE CScriptGameObject::GetRank () { CAI_Stalker *stalker = smart_cast<CAI_Stalker*>(&object()); if (!stalker) { ai().script_engine().script_log (ScriptStorage::eLuaMessageTypeError,"CAI_Stalker : cannot access class member GetRank!"); return (CHARACTER_RANK_VALUE(0)); } else return (stalker->Rank()); }
void RELATION_REGISTRY::Action (CEntityAlive* from, CEntityAlive* to, ERelationAction action) { static CHARACTER_GOODWILL friend_kill_goodwill = pSettings->r_s32(ACTIONS_POINTS_SECT, "friend_kill_goodwill"); static CHARACTER_GOODWILL neutral_kill_goodwill = pSettings->r_s32(ACTIONS_POINTS_SECT, "neutral_kill_goodwill"); static CHARACTER_GOODWILL enemy_kill_goodwill = pSettings->r_s32(ACTIONS_POINTS_SECT, "enemy_kill_goodwill"); static CHARACTER_GOODWILL community_member_kill_goodwill = pSettings->r_s32(ACTIONS_POINTS_SECT, "community_member_kill_goodwill"); static CHARACTER_REPUTATION_VALUE friend_kill_reputation = pSettings->r_s32(ACTIONS_POINTS_SECT, "friend_kill_reputation"); static CHARACTER_REPUTATION_VALUE neutral_kill_reputation = pSettings->r_s32(ACTIONS_POINTS_SECT, "neutral_kill_reputation"); static CHARACTER_REPUTATION_VALUE enemy_kill_reputation = pSettings->r_s32(ACTIONS_POINTS_SECT, "enemy_kill_reputation"); //(с) мин. время через которое снова будет зарегестрировано сообщение об атаке на персонажа static u32 min_attack_delta_time = u32(1000.f * pSettings->r_float(ACTIONS_POINTS_SECT, "min_attack_delta_time")); static CHARACTER_GOODWILL friend_fight_help_goodwill = pSettings->r_s32(ACTIONS_POINTS_SECT, "friend_fight_help_goodwill"); static CHARACTER_GOODWILL neutral_fight_help_goodwill = pSettings->r_s32(ACTIONS_POINTS_SECT, "neutral_fight_help_goodwill"); static CHARACTER_GOODWILL enemy_fight_help_goodwill = pSettings->r_s32(ACTIONS_POINTS_SECT, "enemy_fight_help_goodwill"); static CHARACTER_GOODWILL community_member_fight_help_goodwill = pSettings->r_s32(ACTIONS_POINTS_SECT, "community_member_fight_help_goodwill"); static CHARACTER_REPUTATION_VALUE friend_fight_help_reputation = pSettings->r_s32(ACTIONS_POINTS_SECT, "friend_fight_help_reputation"); static CHARACTER_REPUTATION_VALUE neutral_fight_help_reputation = pSettings->r_s32(ACTIONS_POINTS_SECT, "neutral_fight_help_reputation"); static CHARACTER_REPUTATION_VALUE enemy_fight_help_reputation = pSettings->r_s32(ACTIONS_POINTS_SECT, "enemy_fight_help_reputation"); CActor* actor = smart_cast<CActor*> (from); CInventoryOwner* inv_owner_from = smart_cast<CInventoryOwner*> (from); CAI_Stalker* stalker_from = smart_cast<CAI_Stalker*> (from); CAI_Stalker* stalker = smart_cast<CAI_Stalker*> (to); //вычисление изменения репутации и рейтинга пока ведется //только для актера if(!inv_owner_from || from->cast_base_monster()) return; ALife::ERelationType relation = ALife::eRelationTypeDummy; if(stalker) { stalker->m_actor_relation_flags.set(action, TRUE); relation = GetRelationType(smart_cast<CInventoryOwner*>(stalker), inv_owner_from); } switch(action) { case ATTACK: { if(actor) { //учитывать ATTACK и FIGHT_HELP, только если прошло время //min_attack_delta_time FIGHT_DATA* fight_data_from = FindFight (from->ID(), true); if(Device.dwTimeGlobal - fight_data_from->attack_time < min_attack_delta_time) break; fight_data_from->attack_time = Device.dwTimeGlobal; //если мы атаковали персонажа или монстра, который //кого-то атаковал, то мы помогли тому, кто защищался FIGHT_DATA* fight_data = FindFight (to->ID(),true); if(fight_data) { CAI_Stalker* defending_stalker = smart_cast<CAI_Stalker*>(Level().Objects.net_Find(fight_data->defender)); if(defending_stalker) { CAI_Stalker* attacking_stalker = smart_cast<CAI_Stalker*>(Level().Objects.net_Find(fight_data->attacker)); Action(actor, defending_stalker, attacking_stalker?FIGHT_HELP_HUMAN:FIGHT_HELP_MONSTER); } } } if(stalker) { bool bDangerScheme = false; const CEntityAlive* stalker_enemy = stalker->memory().enemy().selected(); if(actor && stalker_enemy) { const CInventoryOwner* const_inv_owner_from = inv_owner_from; if(stalker_enemy->human_being()) { const CInventoryOwner* const_inv_owner_stalker_enemy = smart_cast<const CInventoryOwner*>(stalker_enemy); ALife::ERelationType relation_to_actor = GetRelationType(const_inv_owner_stalker_enemy, const_inv_owner_from); if(relation_to_actor == ALife::eRelationTypeEnemy) bDangerScheme = true; } } SAttackGoodwillStorage* st = bDangerScheme?&gw_danger:&gw_free; CHARACTER_GOODWILL delta_goodwill = 0; CHARACTER_REPUTATION_VALUE delta_reputation = 0; switch (relation) { case ALife::eRelationTypeEnemy: { delta_goodwill = st->enemy_attack_goodwill; delta_reputation = st->enemy_attack_reputation; }break; case ALife::eRelationTypeNeutral: { delta_goodwill = st->neutral_attack_goodwill; delta_reputation = st->neutral_attack_reputation; }break; case ALife::eRelationTypeFriend: { delta_goodwill = st->friend_attack_goodwill; delta_reputation = st->friend_attack_reputation; }break; }; //сталкер при нападении на членов своей же группировки отношения не меняют //(считается, что такое нападение всегда случайно) // change relation only for pairs actor->stalker, do not use pairs stalker->stalker bool stalker_attack_team_mate = stalker && stalker_from; if (delta_goodwill && !stalker_attack_team_mate) { //изменить отношение ко всем членам атакованой группы (если такая есть) //как к тому кого атаковали CGroupHierarchyHolder& group = Level().seniority_holder().team(stalker->g_Team()).squad(stalker->g_Squad()).group(stalker->g_Group()); for(std::size_t i = 0; i < group.members().size(); i++) { ChangeGoodwill(group.members()[i]->ID(), from->ID(), delta_goodwill); } //*(CHARACTER_GOODWILL)( stalker->Sympathy() * (float)(delta_goodwill)); CHARACTER_GOODWILL community_goodwill = (CHARACTER_GOODWILL)( stalker->Sympathy() * (float)(st->community_member_attack_goodwill) ); if (community_goodwill) { ChangeCommunityGoodwill(stalker->Community(), from->ID(), community_goodwill); } } if(delta_reputation) { inv_owner_from->ChangeReputation(delta_reputation); } } } break; case KILL: { if(stalker) { //FIGHT_DATA* fight_data_from = FindFight (from->ID(), true); //мы помним то, какое отношение обороняющегося к атакующему //было перед началом драки ALife::ERelationType relation_before_attack = ALife::eRelationTypeDummy; //if(fight_data_from) // relation_before_attack = fight_data_from->defender_to_attacker; //else relation_before_attack = relation; CHARACTER_GOODWILL delta_goodwill = 0; CHARACTER_REPUTATION_VALUE delta_reputation = 0; switch (relation_before_attack) { case ALife::eRelationTypeEnemy: { delta_goodwill = enemy_kill_goodwill; delta_reputation = enemy_kill_reputation; }break; case ALife::eRelationTypeNeutral: { delta_goodwill = neutral_kill_goodwill; delta_reputation = neutral_kill_reputation; }break; case ALife::eRelationTypeFriend: { delta_goodwill = friend_kill_goodwill; delta_reputation = friend_kill_reputation; }break; }; //сталкер при нападении на членов своей же группировки отношения не меняют //(считается, что такое нападение всегда случайно) bool stalker_kills_team_mate = stalker_from && (stalker_from->Community() == stalker->Community()); if(delta_goodwill && !stalker_kills_team_mate) { //изменить отношение ко всем членам группы (если такая есть) //убитого, кроме него самого CGroupHierarchyHolder& group = Level().seniority_holder().team(stalker->g_Team()).squad(stalker->g_Squad()).group(stalker->g_Group()); for(std::size_t i = 0; i < group.members().size(); i++) { if(stalker->ID() != group.members()[i]->ID()) { ChangeGoodwill(group.members()[i]->ID(), from->ID(), delta_goodwill); } } //(CHARACTER_GOODWILL)( stalker->Sympathy() * (float)(delta_goodwill+community_member_kill_goodwill)); CHARACTER_GOODWILL community_goodwill = (CHARACTER_GOODWILL)( stalker->Sympathy() * (float)(community_member_kill_goodwill) ); if (community_goodwill) { ChangeCommunityGoodwill(stalker->Community(), from->ID(), community_goodwill); } } if(delta_reputation) { inv_owner_from->ChangeReputation(delta_reputation); } CHARACTER_RANK_VALUE delta_rank = 0; delta_rank = CHARACTER_RANK::rank_kill_points(CHARACTER_RANK::ValueToIndex(stalker->Rank())); if(delta_rank) inv_owner_from->ChangeRank(delta_rank); } } break; case FIGHT_HELP_HUMAN: case FIGHT_HELP_MONSTER: { if(stalker && stalker->g_Alive()) { CHARACTER_GOODWILL delta_goodwill = 0; CHARACTER_REPUTATION_VALUE delta_reputation = 0; switch (relation) { case ALife::eRelationTypeEnemy: { delta_goodwill = enemy_fight_help_goodwill; delta_reputation = enemy_fight_help_reputation; }break; case ALife::eRelationTypeNeutral: { delta_goodwill = neutral_fight_help_goodwill; delta_reputation = neutral_fight_help_reputation; }break; case ALife::eRelationTypeFriend: { delta_goodwill = friend_fight_help_goodwill; delta_reputation = friend_fight_help_reputation; }break; }; if(delta_goodwill) { //изменить отношение ко всем членам атакованой группы (если такая есть) //как к тому кого атаковали CGroupHierarchyHolder& group = Level().seniority_holder().team(stalker->g_Team()).squad(stalker->g_Squad()).group(stalker->g_Group()); for(std::size_t i = 0; i < group.members().size(); i++) { ChangeGoodwill(group.members()[i]->ID(), from->ID(), delta_goodwill); } //* ChangeCommunityGoodwill(stalker->Community(), from->ID(), (CHARACTER_GOODWILL)( stalker->Sympathy() * (float)delta_goodwill )); CHARACTER_GOODWILL community_goodwill = (CHARACTER_GOODWILL)( stalker->Sympathy() * (float)(community_member_fight_help_goodwill) ); if (community_goodwill) { ChangeCommunityGoodwill(stalker->Community(), from->ID(), community_goodwill); } } if(delta_reputation) { inv_owner_from->ChangeReputation(delta_reputation); } } } break; } }