📄 player.cpp
字号:
int dest_y = m_way_points.back().second ;
if ( test_goal() || ( abs(x - dest_x) < context->GetWalkingSpeed() && abs( y - dest_y ) < context->GetWalkingSpeed() ) )
{
// 到达一个目的地,弹出队列
m_way_points.pop_back() ;
if ( is_loop )
{
m_backup_way_points.push_front( make_pair(dest_x, dest_y) ) ;
}
if ( !m_way_points.empty() )
{
// 还有目标点在队列中,继续移动
compute_dxy() ;
x += way_point_dx ;
y += way_point_dy ;
consist_way_time-- ;
this->EnterWaitingMode( 1000 ) ;
}
else
{
if ( is_loop )
{
m_way_points = m_backup_way_points ;
m_backup_way_points.clear() ;
compute_dxy() ;
x += way_point_dx ;
y += way_point_dy ;
consist_way_time-- ;
this->EnterWaitingMode( 1000 ) ;
}
else
{
// 没有目标点,结束移动
is_doing_task = false ;
this->state = CGameLogic::STOP ;
}
}
}
else
{
if (consist_way_time < 0)
{
compute_dxy() ;
}
consist_way_time -- ;
// 按原路线不能走通就选择新路线
if ( context->GetLogicalMapInfo( x + way_point_dx, y + way_point_dy ) == 0 )
{
compute_dxy() ;
}
if ( !this->DetectOtherActor(2 * way_point_dx, 2 * way_point_dy) )
{
x += way_point_dx ;
y += way_point_dy ;
}
else
{
this->EnterWaitingMode( 5000 ) ;
}
}
}
return is_doing_task ;
}
/*
* 动态计算地图两点间举例
*/
double CPlayer::ActiveLength(int x1, int y1, int x2, int y2)
{
if ( context->GetLogicalMapInfo(x1, y1) != 0 )
{
return sqrt( (double)( x2 - x1 ) * ( x2 - x1 ) + ( y2 - y1 ) * ( y2 - y1 ) ) ;
}
else
{
return 3e10 ;
}
}
bool CPlayer::test_goal()
{
int dest_x = m_way_points.back().first ;
int dest_y = m_way_points.back().second ;
int old_way_point_dx = way_point_dx ;
int old_way_point_dy = way_point_dy ;
int old_consist_way_time = consist_way_time ;
double length = compute_dxy() ;
if ( length <= context->GetWalkingSpeed() )
{
return true ;
}
else
{
way_point_dx = old_way_point_dx ;
way_point_dy = old_way_point_dy ;
consist_way_time = old_consist_way_time ;
return false ;
}
}
void CPlayer::set_task_loop(bool is_loop)
{
this->is_loop = is_loop ;
}
void CPlayer::EnterWaitingMode(unsigned int time )
{
this->state = CGameLogic::STOP ;
way_point_dx = 0 ;
way_point_dy = 0 ;
waiting_time = time ;
waiting_mode = true ;
start_time = timeGetTime() ;
}
bool CPlayer::DetectOtherActor(int dx, int dy)
{
// 枚举压栈
context->m_ActorManager->push_enum_state() ;
CPlayer* other = context->m_ActorManager->enumActor() ;
bool flag = false ;
while ( other != NULL )
{
if ( other != this && other->active_in_scene && ActiveLength( other->x, other->y, this->x + dx, this->y + dy ) <= context->GetSensitiveLength() )
{
flag = true ;
}
other = context->m_ActorManager->enumActor() ;
}
// 枚举出栈
context->m_ActorManager->pop_enum_state() ;
return flag ;
}
void CPlayer::push_script(std::string& ProcName )
{
m_talking_script.push_back(ProcName) ;
}
string& CPlayer::TalkScript()
{
size_t i ;
switch( m_talk_state )
{
// 随机的时候,就随机取脚本执行
case RANDOM :
i = rand() % m_talking_script.size() ;
return m_talking_script[i] ;
break;
case CONTINUAL:
if ( m_current_words < m_talking_script.size() )
{
return m_talking_script[ m_current_words++ ] ;
}
else
{
return m_talking_script[ m_current_words-1 ] ;
}
break ;
case CONDITIONAL :
return m_talking_script[ m_current_words ] ;
break;
case LOOP :
if ( m_current_words < m_talking_script.size() )
{
return m_talking_script[ m_current_words++ ] ;
}
else
{
m_current_words = 0 ;
return m_talking_script[ m_current_words++ ] ;
}
break;
default:
throw runtime_error("Incredible error in CPlayer::TalkScript()") ;
break;
}
}
void CPlayer::SetTalkState(TalkState state)
{
m_talk_state = state ;
}
void CPlayer::NextTalking(string& ProcName )
{
vector<string>::iterator pos = find( m_talking_script.begin(), m_talking_script.end(), ProcName ) ;
if ( pos != m_talking_script.end() )
{
m_current_words = pos - m_talking_script.begin() ;
}
else
{
throw logic_error("Required procedure is not in actor's list!") ;
}
}
void CPlayer::SetInfoText(const std::string& info )
{
m_attack_str_buf = info ;
this->attack_str = m_attack_str_buf.c_str() ;
GetFrameCount(&m_frame_count_for_info) ;
}
void CPlayer::CheckMovFrameEnd()
{
size_t now_frame ;
GetFrameCount( &now_frame ) ;
// 检查停止播放信息字符
if ( now_frame - m_frame_count_for_info > FRAMENUMFORTEXT && this->attack_str != NULL )
{
this->attack_str = NULL ;
}
// 检查停止播放人物动画
if ( now_frame - m_frame_count_for_movie > FRAMENUMFORMOV && this->state == CGameLogic::FIGHTING )
{
this->state = CGameLogic::STOP ;
}
}
void CPlayer::NpcFight(std::string& fighter_name )
{
// Random选择攻击招数
size_t selector = rand() % m_skills.size() ;
Attack( m_skills.begin()->description, fighter_name ) ;
}
void CPlayer::PlayFightMovie()
{
// 开始播放动画
this->state = CGameLogic::FIGHTING ;
GetFrameCount(&m_frame_count_for_movie) ;
}
void CPlayer::Attack(std::string& skill, std::string& name )
{
SPropertyItem* attack_skill = this->Skill(skill) ;
CPlayer& actor = this->context->m_ActorManager->GetActor( name ) ;
stringstream info ;
if ( attack_skill->name == "内定" )
{
if ( attack_skill->description == "法术:如沐春风" )
{
if ( Property("魔法力")->val + attack_skill->val > 0 )
{
this->ChangeProperty( "魔法力", attack_skill->val ) ;
this->ChangeProperty( "生命力", this->Property("生命力上限")->val * 2 / 3 );
info << "<size=8><color=65535>生命力恢复到66%!" ;
SetInfoText( info.str() ) ;
Speak("如沐春风") ;
}
else
{
// 法术失败
info << "<size=8><color=255>法术失败!" ;
SetInfoText( info.str() ) ;
Speak("法术失败");
}
}
}
else
{
// 对对方造成伤害
int val = - ( rand() % this->Property("攻击力")->val ) ;
val += attack_skill->val ;
actor.ChangeProperty(attack_skill->name, val) ;
info << "<size=8><color=255>受到攻击: " << val ;
// 对方播放信息字符
actor.SetInfoText( info.str() ) ;
// 自己播放攻击动画
PlayFightMovie() ;
// 播放声音
Speak( "挥剑" ) ;
}
context->m_EventManager->Wait( FRAMENUMFORTEXT + 5 ) ;
}
void CPlayer::TryEscape(const std::string& name )
{
vector<string> Argu ;
// 根据速度来判断是否能够逃脱
int npc_speed = context->m_ActorManager->GetActor(name).Property("速度")->val ;
int my_speed = Property("速度")->val ;
Argu.push_back(this->name) ;
Argu.push_back(name) ;
if ( rand() % ( npc_speed + my_speed ) <= my_speed )
{
context->m_EventManager->Do_Event("escape_success", &Argu) ;
}
else
{
context->m_EventManager->Call_Event("escape_fail", &Argu) ;
}
}
void CPlayer::ChangeProperty(const string& property, int val )
{
SPropertyItem* item = this->Property( property ) ;
SPropertyItem* topval = this->Property( property+"上限" ) ;
item->val += val ;
if ( item->val > topval->val )
{
item->val = topval->val ;
}
// 处理升级问题
int upgrade_line = 100 * ( 1 << (this->Property("等级")->val - 1) ) ;
if ( property == "经验" )
{
while ( item->val >= upgrade_line )
{
// 提升一个等级
this->Property("等级")->val++ ;
// 各项属性上限分别提升
this->Property("生命力上限")->val += this->Property("+生命力")->val ;
this->Property("魔法力上限")->val += this->Property("+魔法力")->val ;
this->Property("速度上限")->val += this->Property("+速度")->val ;
this->Property("攻击力上限")->val += this->Property("+攻击力")->val ;
this->Property("速度")->val = this->Property("速度上限")->val ;
this->Property("生命力")->val = this->Property("生命力上限")->val ;
this->Property("魔法力")->val = this->Property("魔法力上限")->val ;
upgrade_line = 100 * ( 1 << (this->Property("等级")->val - 1) ) ;
// 播放音效
Speak("升级") ;
// 播放字幕
this->SetInfoText("<size=10>等级 +1") ;
}
}
}
void CPlayer::Die()
{
this->active_in_scene = false ;
this->is_dead = true ;
if ( this == &( context->m_ActorManager->GetActiveActor() ) )
{
context->m_is_dead = true ;
}
}
void CPlayer::AutoAttack(bool val)
{
this->is_auto_attack = val ;
}
void CPlayer::LearnSkill(const SPropertyItem& skill )
{
m_skills.push_back( skill ) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -