EventManager.cpp
上传用户:lian_0917
上传日期:2013-03-24
资源大小:1151k
文件大小:21k
源码类别:

其他游戏

开发平台:

MultiPlatform

  1. #include "StdAfx.h"
  2. #include "./eventmanager.h"
  3. #include "./callback_functions.h"
  4. #include "gamelogic.h"
  5. using namespace std ;
  6. CEventManager::CEventManager(CGameLogic* contex)
  7. {
  8. this->contex = contex ;
  9. is_doing_event = false ;
  10. wait_for_enter = false ;
  11. // 背景默认状态:不作淡入
  12. m_background_state = BackGround_Normal ;
  13. m_frame_count = 0 ;
  14. m_waiting_frame = 0 ;
  15. m_is_doing_logic_wait = false ;
  16. }
  17. CEventManager::~CEventManager(void)
  18. {
  19. }
  20. /*
  21.  * 读取脚本进入缓冲,比如第一幕
  22.  */
  23. void CEventManager::LoadScene(std::string scenefile)
  24. {
  25. event_lib.clear() ;
  26. scenefile.insert(0, ".\Scenes\") ;
  27. ifstream in(scenefile.c_str()) ;
  28. stringstream stream ;
  29. string ProcName ;
  30. int first;
  31. int second ;
  32. string Actorname ;
  33. string BackBmpName ;
  34. string MaskBmpName ;
  35. stream.rdbuf()->str( readin( in ) )  ;
  36. if ( in.is_open() )
  37. {
  38. // 读事件关系表
  39. stream >> first >> second ;
  40. while ( first != -1 ) 
  41. {
  42. /* 触发事件 */
  43. relation_lib.insert( make_pair( first, second ) ) ;
  44. stream.clear() ;
  45. stream.rdbuf()->str(readin( in ) ) ;
  46. stream >> first >> second ;
  47. }
  48. stream.clear() ;
  49. stream.rdbuf()->str(readin( in ) ) ;
  50. // 读默认开始事件
  51. stream >> now_event ;
  52. vector<string> temp ;
  53. string reserve_word ;
  54. // 读所有事件进入事件库
  55. stream.clear() ;
  56. stream.rdbuf()->str(readin( in ) ) ;
  57. stream >> reserve_word >> ProcName ;
  58. while ( ProcName != "END" )
  59. {
  60. stream.clear() ;
  61. stream.rdbuf()->str(readin( in ) ) ;
  62. while ( stream.str() != "END" )
  63. {
  64. temp.push_back( stream.str() ) ;
  65. stream.clear() ;
  66. stream.rdbuf()->str(readin( in ) ) ;
  67. }
  68. event_lib.push_back( make_pair( ProcName, temp) ) ;
  69. temp.clear() ;
  70. stream.clear() ;
  71. stream.rdbuf()->str(readin( in ) ) ;
  72. stream >> reserve_word >> ProcName ;
  73. }
  74. PosIterator( now_event, 0, pos_in_a_event ) ;
  75. // 初始状态:一般状态
  76. m_background_state = BackGround_Normal ;
  77. m_is_in_state = false ;
  78. is_doing_event = true ;
  79. call_record.insert(now_event) ;
  80. this->Continue_Doing() ;
  81. // 提起执行脚本初始化部分
  82. while ( !wait_for_enter && this->Has_something_todo() ) 
  83. {
  84. this->Continue_Doing() ;
  85. }
  86. }
  87. }
  88. /*
  89.  * 从文件读入一行脚本:忽略注释
  90.  */
  91. string CEventManager::readin( std::ifstream& in )
  92. {
  93. char buf[512] ;
  94. string ret ;
  95. in.getline(buf, 512) ;
  96. while ( buf[0] == ';' || buf[0] == '' )
  97. {
  98. in.getline(buf, 128) ;
  99. }
  100. ret = buf ;
  101. return ret ;
  102. }
  103. /*
  104.  * 是否正在执行情节脚本
  105.  */
  106. bool CEventManager::Has_something_todo()
  107. {
  108. return is_doing_event ;
  109. }
  110. /*
  111.  * 脚本解释部分:根据脚本执行不同的操作
  112.  */
  113. void CEventManager::Executer(std::stringstream& stream )
  114. {
  115. string cmd ;
  116. stream >> cmd ;
  117. if ( cmd == "SAY" )
  118. {
  119. /* 这里处理人物对话 */
  120. contex->m_talking_board.actived = true ;
  121. contex->m_GameState = CGameLogic::TALKING ;
  122. string talker ;
  123. string lisenner ;
  124. string words ;
  125. stream >> talker >> lisenner >> words ;
  126. contex->m_talking_board.Talker_id = contex->m_ActorManager->GetActor(talker).face_Res_id ;
  127. contex->m_talking_board.words = words ;
  128. }
  129. else if ( cmd == "FIND" )
  130. {
  131. string item ;
  132. string description ;
  133. string property ;
  134. int val ;
  135. /* 找到道具 */
  136. contex->m_discovery_board.actived = true ;
  137. stream >> item >> description >> property >> val ;
  138. contex->m_discovery_board.item = contex->m_ActorManager->GetSimpleObj( item ).ResID ;
  139. contex->m_discovery_board.description = description ;
  140. SPropertyItem tool ;
  141. tool.name = property ;
  142. tool.description = description ;
  143. tool.icon_id = contex->m_discovery_board.item ;
  144. tool.val = val ;
  145. contex->m_ActorManager->GetActiveActor().AddTool( tool ) ;
  146. }
  147. else if ( cmd == "SHOWTEXT" )
  148. {
  149. string text ;
  150. contex->m_discovery_board.actived = true ;
  151. stream >> text ;
  152. contex->m_discovery_board.description = text ;
  153. contex->m_discovery_board.item = -1 ;
  154. }
  155. else if ( cmd == "SHOW_STA" )
  156. {
  157. stringstream text ;
  158. contex->m_discovery_board.actived = true ;
  159. text << "<size=12>      牛二牺牲了……</p>" ;
  160. text << "    <color=16777215>在牛二死之前,您玩出</p>了本游戏 " ;
  161. text << 100 * (double)call_record.size() / this->event_lib.size() ;
  162. text << "% 的剧情</p>,别哭泣,别气馁,再接再</p>厉!</p>" ;
  163. text << "    回车返回主菜单。" ;
  164. contex->m_discovery_board.item = -1 ;
  165. contex->m_discovery_board.description = text.str() ;
  166. }
  167. else if ( cmd == "LEARN" )
  168. {
  169. string description ;
  170. string property ;
  171. int val ;
  172. string actor ;
  173. string temp ;
  174. /* 学会技能 */
  175. contex->m_discovery_board.actived = true ;
  176. stream >> actor >> description >> property >> val ;
  177. contex->m_discovery_board.item = contex->m_ActorManager->GetSimpleObj( "菜刀" ).ResID ;
  178. temp = "速成" ;
  179. temp += description ;
  180. contex->m_discovery_board.description = temp ;
  181. SPropertyItem skill ;
  182. skill.name = property ;
  183. skill.description = description ;
  184. skill.icon_id = -1 ;
  185. skill.val = val ;
  186. contex->m_ActorManager->GetActor(actor).LearnSkill( skill ) ;
  187. }
  188. else if ( cmd == "LEARNEND" )
  189. {
  190. contex->m_discovery_board.actived = false ;
  191. }
  192. else if ( cmd == "SHUTUP" )
  193. {
  194. contex->m_talking_board.actived = false ;
  195. }
  196. else if ( cmd == "FINDCLOSE" )
  197. {
  198. contex->m_discovery_board.actived = false ;
  199. }
  200. else if ( cmd == "CLOSEINPUTS" )
  201. {
  202. contex->m_bAccept_user_inputs = false ;
  203. }
  204. else if ( cmd == "OPENINPUTS")
  205. {
  206. contex->m_bAccept_user_inputs = true ;
  207. }
  208. else if ( cmd == "FADEIN" )
  209. {
  210. this->m_background_state = BackGround_Fadein ;
  211. this->m_is_in_state = false ;
  212. }
  213. else if ( cmd == "FADEOUT" )
  214. {
  215. this->m_background_state = BackGround_Fadeout ;
  216. this->m_is_in_state = false ;
  217. }
  218. else if ( cmd == "SPEAK" )
  219. {
  220. string file ;
  221. stream >> file ;
  222. Speak( file.c_str() ) ;
  223. }
  224. else if ( cmd == "LOADMUSIC" )
  225. {
  226. string file ;
  227. stream >> file ;
  228. LoadMusic( file.c_str() ) ;
  229. }
  230. else if ( cmd == "PLAYMUSIC" )
  231. {
  232. PlayMusic(true) ;
  233. }
  234. else if ( cmd == "STOPMUSIC" )
  235. {
  236. StopMusic() ;
  237. }
  238. else if ( cmd == "WAITKEY" )
  239. {
  240. wait_for_enter = true ;
  241. }
  242. else if ( cmd == "LOADSCENE" )
  243. {
  244. string scene_name, mask_name ;
  245. int logical_map ;
  246. stream >> scene_name >> mask_name >> logical_map ;
  247. this->ChangeScene(scene_name, mask_name, logical_map) ;
  248. }
  249. else if (cmd == "ACTIVEACTOR")
  250. {
  251. string ActorName ;
  252. int ActorX, ActorY, ActorFacing ;
  253. stream >> ActorName >> ActorX >> ActorY >> ActorFacing ;
  254. CPlayer& actor = this->contex->m_ActorManager->GetActor(ActorName) ;
  255. if ( !actor.is_dead )
  256. {
  257. actor.active_in_scene = true ;
  258. actor.facing = ActorFacing ;
  259. actor.x = ActorX ;
  260. actor.y = ActorY ;
  261. }
  262. }
  263. else if ( cmd == "KILLACTOR" )
  264. {
  265. string name ;
  266. stream >> name ;
  267. CPlayer& player = this->contex->m_ActorManager->GetActor(name) ;
  268. player.Die() ;
  269. }
  270. else if ( cmd == "USERCONTROL" )
  271. {
  272. string name ;
  273. stream >> name ;
  274. this->contex->m_ActorManager->SetActiveActor(name) ;
  275. }
  276. else if ( cmd == "DISABLEACTOR")
  277. {
  278. string ActorName ;
  279. stream >> ActorName ;
  280. this->contex->m_ActorManager->GetActor(ActorName).active_in_scene = false ;
  281. }
  282. else if ( cmd == "GOTO" ) /* 跳转到某个过程执行 */
  283. {
  284. string proc ;
  285. stream >> proc ;
  286. Do_Event( proc ) ;
  287. }
  288. else if ( cmd == "CALL" )   /* 调用某个过程执行 */
  289. {
  290. string proc ;
  291. string Argu ;
  292. vector<string> Argu_list ;
  293. stream >> proc >> Argu ;
  294. /*
  295.  * 参数压栈
  296.  */
  297. while ( Argu != "CALLEND" )
  298. {
  299. Argu_list.push_back(Argu) ;
  300. stream >> Argu ;
  301. }
  302. Call_Event( proc, &Argu_list) ;
  303. }
  304. else if ( cmd == "RET" )    /* 过程返回 */
  305. {
  306. Return_from_Event() ;
  307. }
  308. else if ( cmd == "SHIFTACTOR" )
  309. {
  310. string name ;
  311. string state ;
  312. stream >> name >> state ;
  313. CPlayer& actor = this->contex->m_ActorManager->GetActor(name) ;
  314. if ( state == "BIG" )
  315. {
  316. actor.SetActiveRes( CPlayer::BIG ) ;
  317. }
  318. else if ( state == "SMALL" )
  319. {
  320. actor.SetActiveRes( CPlayer::SMALL ) ;
  321. }
  322. else if ( state == "MID" )
  323. {
  324. actor.SetActiveRes( CPlayer::MID ) ;
  325. }
  326. }
  327. else if ( cmd == "WALKSPEED" )
  328. {
  329. string speed ;
  330. stream >> speed ;
  331. if ( speed == "FAST" )
  332. {
  333. contex->SetWalkingSpeed( CGameLogic::FASTMODE ) ;
  334. }
  335. else if ( speed == "SLOW" )
  336. {
  337. contex->SetWalkingSpeed( CGameLogic::SLOWMODE ) ;
  338. }
  339. }
  340. else if ( cmd == "STARTFIGHT" )
  341. {
  342. string name ;
  343. string npc_name ;
  344. stream >> name >> npc_name ;
  345. contex->StartFight(name, npc_name) ;
  346. }
  347. else if ( cmd == "ENDFIGHT" )
  348. {
  349. string name ;
  350. stream >> name ;
  351. contex->EndFight( name ) ;
  352. }
  353. else if ( cmd == "NPCFIGHT" )
  354. {
  355. string npc_name ;
  356. string user_name ;
  357. stream >> npc_name >> user_name ;
  358. contex->m_ActorManager->GetActor( npc_name ).NpcFight( user_name ) ;
  359. }
  360. else if ( cmd == "FIGHTMENU" )
  361. {
  362. contex->BringUpMenu( CGameLogic::MENU3 ) ;
  363. }
  364. else if ( cmd == "IF" )
  365. {
  366. string condition_src ;
  367. string op ;
  368. string condition_dest ;
  369. string temp ;
  370. stringstream then_stmt ;
  371. stringstream else_stmt ;
  372. int nest_count = 0 ;
  373. stream >> condition_src >> op >> condition_dest >> temp;
  374. if ( temp != "THEN" )
  375. {
  376. temp.insert(0, "script error: 'THEN' expected, but found: ") ;
  377. throw exception( temp.c_str() ) ;
  378. }
  379. else
  380. {
  381. /* 读取then部分,直到读到else为止 */
  382. stream >> temp ;
  383. while ( temp != "ELSE" || nest_count != 0 )
  384. {
  385. if ( temp == "IF" )
  386. {
  387. nest_count++ ;
  388. }
  389. if ( temp == "ENDIF" )
  390. {
  391. nest_count-- ;
  392. }
  393. then_stmt << temp << ' ';
  394. stream >> temp ;
  395. }
  396. /* 读else部分,直到读到ENDIF为止 */
  397. stream >> temp ;
  398. while ( temp != "ENDIF" || nest_count != 0 )
  399. {
  400. if ( temp == "IF" )
  401. {
  402. nest_count++ ;
  403. }
  404. if ( temp == "ENDIF" )
  405. {
  406. nest_count-- ;
  407. }
  408. else_stmt << temp << ' ' ;
  409. stream >> temp ;
  410. }
  411. }
  412. /* 根据条件选择执行 */
  413. string name ;
  414. string property ;
  415. size_t pos = condition_src.find('.') ;
  416. bool cond ;
  417. /* 解析人物属性操作,如 牛二.生命力 */
  418. name = condition_src.substr( 0, pos ) ;
  419. property = condition_src.substr( pos+1, condition_src.length() ) ;
  420. CPlayer& Actor = this->contex->m_ActorManager->GetActor( name ) ;
  421. if ( op == ">" )
  422. {
  423. SPropertyItem* item = Actor.Property( property ) ;
  424. cond = ( item->val > atoi( condition_dest.c_str() ) ) ;
  425. }
  426. else if ( op == "<" )
  427. {
  428. SPropertyItem* item = Actor.Property( property ) ;
  429. cond = ( item->val < atoi( condition_dest.c_str() ) ) ;
  430. }
  431. else if ( op == ">=" )
  432. {
  433. SPropertyItem* item = Actor.Property( property ) ;
  434. cond = ( item->val >= atoi( condition_dest.c_str() ) ) ;
  435. }
  436. else if ( op == "<=" )
  437. {
  438. SPropertyItem* item = Actor.Property( property ) ;
  439. cond = ( item->val <= atoi( condition_dest.c_str() ) ) ;
  440. }
  441. else if ( op == "==" )
  442. {
  443. SPropertyItem* item = Actor.Property( property ) ;
  444. cond = ( item->val == atoi( condition_dest.c_str() ) ) ;
  445. }
  446. else if ( op == "HAS" )
  447. {
  448. if ( property == "装备" )
  449. {
  450. SPropertyItem* item = Actor.FindTools( condition_dest ) ;
  451. if ( item == NULL )
  452. {
  453. cond = false ;
  454. }
  455. else
  456. {
  457. cond = true ;
  458. }
  459. }
  460. else if ( property == "技能" )
  461. {
  462. try
  463. {
  464. SPropertyItem* item = Actor.Skill( condition_dest ) ;
  465. cond = true ;
  466. }
  467. catch (...) 
  468. {
  469. cond = false ;
  470. }
  471. }
  472. else
  473. {
  474. throw exception( "script error: actor's property expected in if-stmt" ) ;
  475. }
  476. }
  477. /*
  478.  * 根据解释得来得条件执行
  479.  */
  480. if ( cond )
  481. {
  482. Executer( then_stmt ) ;
  483. }
  484. else
  485. {
  486. Executer( else_stmt ) ;
  487. }
  488. }
  489. else if ( cmd == "NEXTEVENT" )
  490. {
  491. int id ;
  492. stream >> id ;
  493. CPlayer& Actor = contex->m_ActorManager->GetActiveActor() ;
  494. int ix = Actor.x ;
  495. int iy = Actor.y ;
  496. /*
  497.  * 修改逻辑地图,下次可触发事件
  498.  */
  499. contex->m_LogicMap[contex->m_current_map][ix/CGameLogic::granularity][iy/CGameLogic::granularity] = id ;
  500. }
  501. else if ( cmd == "WAYPOINT" )
  502. {
  503. string name ;
  504. string position ;
  505. string temp ;
  506. int x, y ;
  507. stream >> name >> position ;
  508. CPlayer& Actor = contex->m_ActorManager->GetActor( name ) ;
  509. while ( position != "STOP" && position != "LOOP" )
  510. {
  511. size_t pos = position.find_first_of(',') ;
  512. temp = position.substr(1, pos-1) ;
  513. x = atoi( temp.c_str() ) ;
  514. temp = position.substr(pos+1, position.length()-1) ;
  515. y = atoi( temp.c_str() ) ;
  516. Actor.push_way_point( x, y ) ;
  517. stream >> position ;
  518. }
  519. if ( position == "LOOP" )
  520. {
  521. Actor.set_task_loop(true) ;
  522. }
  523. else
  524. {
  525. Actor.set_task_loop(false) ;
  526. }
  527. }
  528. else if ( cmd == "CLEARWAYPOINT" )
  529. {
  530. string npc ;
  531. stream >> npc ;
  532. this->contex->m_ActorManager->GetActor(npc).flush_all_way_point() ;
  533. }
  534. else if ( cmd == "SETFACING" )
  535. {
  536. string npc ;
  537. string point ;
  538. stream >> npc >> point ;
  539. if ( point == "UP" )
  540. {
  541. this->contex->m_ActorManager->GetActor(npc).facing = 2 ;
  542. }
  543. else if ( point == "DOWN" )
  544. {
  545. this->contex->m_ActorManager->GetActor(npc).facing = 0 ;
  546. }
  547. else if ( point == "LEFT" )
  548. {
  549. this->contex->m_ActorManager->GetActor(npc).facing = 1 ;
  550. }
  551. else if ( point == "RIGHT" )
  552. {
  553. this->contex->m_ActorManager->GetActor(npc).facing = 3 ;
  554. }
  555. }
  556. else if ( cmd == "ACTOR_NEXT_TALKING" )
  557. {
  558. string name ;
  559. string proc ;
  560. stream >> name >> proc ;
  561. this->contex->m_ActorManager->GetActor(name).NextTalking( proc ) ;
  562. }
  563. else if ( cmd == "ACTORSHOW" )
  564. {
  565. string name ;
  566. stream >> name ;
  567. /* 人物秀 */
  568. contex->m_discovery_board.actived = true ;
  569. contex->m_discovery_board.item = -1 ;//contex->m_ActorManager->GetActor(name).face_Res_id ;
  570. contex->m_discovery_board.description = contex->m_ActorManager->GetActor(name).self_description.c_str() ;
  571. }
  572. else if ( cmd == "CLOSESHOW" )
  573. {
  574. contex->m_discovery_board.actived = false ;
  575. }
  576. else if ( cmd == "JMP" )
  577. {
  578. int addr ;
  579. stream >> addr ;
  580. this->pos_in_a_event = pos_in_a_event + addr ;
  581. }
  582. else if ( cmd == "INCEXP" )
  583. {
  584. // ActiveActor涨经验
  585. int val ;
  586. stream >> val ;
  587. contex->m_ActorManager->GetActiveActor().ChangeProperty("经验", val) ;
  588. }
  589. else if ( cmd == "DISABLE_AUTO_ATTACK" )
  590. {
  591. string name ;
  592. stream >> name ;
  593. contex->m_ActorManager->GetActor(name).AutoAttack( false ) ;
  594. }
  595. else if ( cmd == "ENABLE_AUTO_ATTACK" )
  596. {
  597. string name ;
  598. stream >> name ;
  599. contex->m_ActorManager->GetActor(name).AutoAttack( true ) ;
  600. }
  601. else if ( cmd == "SET" )
  602. {
  603. string name ;
  604. string property ;
  605. int val ;
  606. stream >> name >> property >> val ;
  607. contex->m_ActorManager->GetActor(name).Property(property)->val = val ;
  608. }
  609. else if ( cmd == "SET_ANGEL" )
  610. {
  611. double angel_up ;
  612. double angel_left ;
  613. stream >> angel_up >> angel_left ;
  614. contex->set_up_walking_angel( angel_up ) ;
  615. contex->set_left_walking_angel( angel_left ) ;
  616. }
  617. else if ( cmd == "THEEND" )
  618. {
  619. /* 当前幕通关 */
  620. contex->m_is_success = true ;
  621. }
  622. else if ( cmd == "LOST" )
  623. {
  624. string description ;
  625. stream >> description ;
  626. contex->m_ActorManager->GetActiveActor().DelTools( description ) ;
  627. }
  628. else if ( cmd == "NOOP" )
  629. {
  630. // 空指令,什么也不作
  631. return ;
  632. }
  633. else
  634. {
  635. cmd.insert(0, "Unrecognized script: ") ;
  636. throw exception( cmd.c_str() ) ;
  637. }
  638. }
  639. /*
  640.  * 按照当前指针取出脚本,调用解释程序
  641.  */
  642. bool CEventManager::Continue_Doing()
  643. {
  644. // 逻辑等待状态不执行脚本
  645. if ( is_logic_waiting() )
  646. {
  647. return false ;
  648. }
  649. if ( pos_in_a_event == FindProc(now_event).end() )
  650. {
  651. is_doing_event = false ;
  652. return false ;
  653. }
  654. string preProcess = *pos_in_a_event ;
  655. string argu = "%1" ;
  656. // 处理参数
  657. for ( int i = 0; i < 9; i++ )
  658. {
  659. argu[1] = i + '1' ;
  660. while (1)
  661. {
  662. size_t pos = preProcess.find(argu) ;
  663. if ( pos == string::npos )
  664. {
  665. break ;
  666. }
  667. preProcess.erase(pos, 2) ;
  668. preProcess.insert(pos, Arguments_list[i]) ;
  669. }
  670. }
  671. stringstream stream ;
  672. stream.rdbuf()->str( preProcess ) ;
  673. // 得到当前script,指针加一
  674. pos_in_a_event++ ;
  675. Executer( stream ) ;
  676. return false ;
  677. }
  678. /*
  679.  * 跳转到某事件执行:类似jump
  680.  */
  681. void CEventManager::Do_Event(int ID, std::vector<std::string>* ArguList)
  682. {
  683. char buf[16] ;
  684. string name = itoa( ID, buf, 10 ) ;
  685. Do_Event(name, ArguList) ;
  686. }
  687. void CEventManager::Do_Event( const string& Proc, std::vector<std::string>* ArguList)
  688. {
  689. now_event = Proc ;
  690. // 如果参数列表不为空,
  691. if ( ArguList != NULL )
  692. {
  693. // 加入新的参数列表
  694. Arguments_list = *ArguList ;
  695. }
  696. pos_in_a_event = FindProc( Proc ).begin() ;
  697. is_doing_event = true ;
  698. wait_for_enter = false ;
  699. // 记录数据便于统计
  700. call_record.insert(Proc) ;
  701. }
  702. /*
  703.  * 调用某事件执行,类似call
  704.  */
  705. void CEventManager::Call_Event(int ID, std::vector<std::string>* ArguList)
  706. {
  707. char buf[16] ;
  708. string name = itoa( ID, buf, 10 ) ;
  709. Call_Event(name) ;
  710. }
  711. void CEventManager::Call_Event(const string& Proc, std::vector<std::string>* ArguList)
  712. {
  713. CallInfo info ;
  714. /*
  715. * 保存现场,压入调用栈
  716. */
  717. info.proc_name = now_event ;
  718. info.ip = pos_in_a_event - FindProc(now_event).begin() ;
  719. info.Scene = this->BackBmpResName ;
  720. info.Mask = this->MaskBmpResName ;
  721. info.logical_map = this->contex->m_current_map ;
  722. // 现场环境和当前参数列表压栈
  723. Call_Stack.push_back( info ) ;
  724. Arguments_Stack.push_back( Arguments_list ) ;
  725. // 如果参数列表不为空,
  726. if ( ArguList != NULL )
  727. {
  728. // 加入新的参数列表
  729. Arguments_list = *ArguList ;
  730. }
  731. else
  732. {
  733. Arguments_list.clear() ;
  734. }
  735. /* 准备新环境 */
  736. now_event = Proc ;
  737. pos_in_a_event = FindProc(Proc).begin() ;
  738. is_doing_event = true ;
  739. wait_for_enter = false ;
  740. // 记录调用,便于统计
  741. call_record.insert(Proc) ;
  742. }
  743. /*
  744.  * 切换场景操作,包括逻辑和图像
  745.  */
  746. void CEventManager::ChangeScene(const std::string& scene_name, const std::string& mask_name, int logical_map)
  747. {
  748. GameRes* res_info ;
  749. int pid ;
  750. res_info = this->contex->GetRes(scene_name) ;
  751. BackBmpResName = scene_name ;
  752. (*LoadBackGround)( res_info->filename.c_str(), res_info->color_key, &pid ) ;
  753. this->BackBmpID = pid ;
  754. res_info = this->contex->GetRes(mask_name) ;
  755. MaskBmpResName = mask_name ;
  756. (*LoadBGMask)( res_info->filename.c_str(), res_info->color_key , &pid ) ;
  757. this->MaskBmpID = pid ;
  758. // 切换逻辑地图
  759. this->contex->UseLogicalMap(logical_map) ;
  760. // 继续执行脚本,以获得场景转换之后的初始化
  761. while ( !wait_for_enter && this->Has_something_todo() ) 
  762. {
  763. this->Continue_Doing() ;
  764. }
  765. }
  766. /*
  767.  * 输入事件号(由于触发事件从256开始编号,所以ID应该大于256),返回后续事件号
  768.  */
  769. int CEventManager::Following_Event(int ID )
  770. {
  771. std::map<int, int>::iterator pos = relation_lib.find( ID ) ;
  772. if ( pos == relation_lib.end() )
  773. {
  774. return -1 ;
  775. }
  776. else
  777. {
  778. return (*pos).second ;
  779. }
  780. }
  781. void CEventManager::PosIterator(int cs, size_t ip, std::vector< std::string>::iterator& pos)
  782. {
  783. char buf[16] ;
  784. string ProcName = itoa(cs, buf, 10) ;
  785. // 转换到新过程的调用
  786. this->PosIterator(ProcName, ip, pos) ;
  787. }
  788. void CEventManager::PosIterator(const std::string& proc, size_t ip, std::vector< std::string>::iterator& pos)
  789. {
  790. try
  791. {
  792. std::vector<std::string>& code = FindProc( proc ) ;
  793. pos = code.begin() + ip ;
  794. }
  795. catch (exception e) 
  796. {
  797. string err = "script error: call non-exsisted procedure " ;
  798. err += proc ;
  799. throw logic_error( err ) ;
  800. }
  801. }
  802. std::vector<std::string>& CEventManager::FindProc( const std::string& ProcName )
  803. {
  804. list< pair<string, vector<string > > >::iterator iter = event_lib.begin() ;
  805. for ( ; iter != event_lib.end(); ++iter )
  806. {
  807. if ( (*iter).first == ProcName )
  808. {
  809. return (*iter).second ;
  810. }
  811. }
  812. string err = "script error: procedure not found " ;
  813. err += ProcName ;
  814. throw logic_error( err ) ;
  815. }
  816. std::vector<std::string>& CEventManager::FindProc( int ProcID )
  817. {
  818. char buf[16] ;
  819. string ProcName = itoa(ProcID, buf, 10) ;
  820. return FindProc( ProcName ) ;
  821. }
  822. void CEventManager::Return_from_Event()
  823. {
  824. CallInfo& info = Call_Stack.back() ;
  825. Arguments_list = Arguments_Stack.back() ;
  826. /* 恢复现场 */
  827. now_event = info.proc_name ;
  828. PosIterator(now_event, info.ip, pos_in_a_event ) ;
  829. is_doing_event = true ;
  830. wait_for_enter = false ;
  831. if ( info.Scene != this->BackBmpResName && info.Mask != this->MaskBmpResName )
  832. {
  833. this->ChangeScene( info.Scene, info.Mask, info.logical_map ) ;
  834. this->m_background_state = BackGround_Fadein ;
  835. this->m_is_in_state = false ;
  836. }
  837. Call_Stack.pop_back() ;
  838. Arguments_Stack.pop_back() ;
  839. }
  840. void CEventManager::Wait(size_t count )
  841. {
  842. GetFrameCount( &m_frame_count ) ;
  843. m_waiting_frame = count ;
  844. m_is_doing_logic_wait = true ;
  845. }
  846. bool CEventManager::is_logic_waiting()
  847. {
  848. size_t now ;
  849. if ( m_is_doing_logic_wait )
  850. {
  851. GetFrameCount( &now ) ;
  852. if ( now - m_frame_count > m_waiting_frame )
  853. {
  854. m_is_doing_logic_wait = false ;
  855. return false ;
  856. }
  857. else
  858. {
  859. return true ;
  860. }
  861. }
  862. else
  863. {
  864. return false ;
  865. }
  866. }