//+-findAngle범위에서 정면 타깃을 검색해서 반환한다(index).탐색에 실패하면-1. private int findForwardTarget(float findAngle) { //자신(정면)과 타깃의 각도로 판정한다. int findIndex = -1; Vector2 forward = new Vector2(transform.forward.x, transform.forward.z).normalized; for (int i = 0; i < targetPlayers.Count; ++i) { chrBehaviorPlayer p = targetPlayers[i]; Vector3 diff = p.transform.position - transform.position; Vector2 targetVec = new Vector2(diff.x, diff.z).normalized; float angle = Vector2.Angle(forward, targetVec); //Debug.Log(angle); //정면에서 각도 범위 내라면 찾은 걸로 한다. if (angle < findAngle) { findAngle = angle; //가장 정면에 있는 대상을 찾고자 검색 범위를 갱신하여 처리를 계속한다. findIndex = i; } } Debug.Log("findForwardTarget:" + findIndex); return(findIndex); }
// 가까이에 있는(퀵 공격할 수 있는) 플레이어를 찾는다. protected chrBehaviorPlayer find_close_player() { chrBehaviorPlayer target = null; foreach (var result in this.control.collision_results) { if (result.object1.tag != "Player") { continue; } chrBehaviorPlayer player = chrBehaviorBase.getBehaviorFromGameObject <chrBehaviorPlayer>(result.object1); if (player == null) { continue; } Vector3 to_player = player.control.getPosition() - this.control.getPosition(); to_player.Normalize(); float pinch = Mathf.Acos(Vector3.Dot(to_player, this.transform.forward)) * Mathf.Rad2Deg; if (pinch > 90.0f) { continue; } target = player; break; } return(target); }
public override void initialize() { this.player = PartyControl.get().getLocalPlayer(); this.player_weapon = this.player.gameObject.findDescendant("anim_wepon"); this.data = GameObject.Find("EventDataIceAtari").GetComponent <EventDataIceAtari>(); // 당첨의 막대 모델. this.ice_bar = this.data.prefab_ice_atari_bar.instantiate(); this.ice_bar.setParent(this.player.gameObject.findDescendant("anim_wrist_R")); this.ice_bar.setLocalPosition(new Vector3(-0.056f, -0.086f, 0.039f)); this.ice_bar.SetActive(false); // "!" 말풍선. this.sprite_bikkuri = Sprite2DRoot.get().createSprite(this.data.texture_bikkuri, true); this.sprite_bikkuri.setVisible(false); // 당첨 말풍선. this.sprite_atari = Sprite2DRoot.get().createSprite(this.data.texture_atari, true); this.sprite_atari.setPosition(new Vector2(0.0f, 150.0f)); this.sprite_atari.setVisible(false); this.sprite_ice_bar = Sprite2DRoot.get().createSprite(this.data.texture_ice_bar, true); this.sprite_ice_bar.setVisible(false); this.sprite_ice_bar.setMaterial(this.data.material_ice_sprite); this.spline = this.data.gameObject.findDescendant("spline_ice").GetComponent <SimpleSplineObject>(); this.tracer.attach(this.spline.curve); }
public override void initializeMap(GameRoot game_root) { MapCreator map_creator = MapCreator.get(); PartyControl party_control = PartyControl.get(); map_creator.setRoomNum(1, 1); map_creator.floor_root_go = new GameObject("Floor"); // 방 만들기. RoomController room = map_creator.createRoomFloor(new Map.RoomIndex(0, 0)); // 더미 방 만들기. map_creator.createVacancy(new Map.RoomIndex(0, -1)); // 방을 구분하는 벽을 만든다. map_creator.createRoomWall(); // 외벽을 만든다. map_creator.createOuterWalls(); GameRoot.get().createLocalPlayer(); GameRoot.get().createNetPlayers(); // 플레이어 위치 설정. chrBehaviorLocal local_player = PartyControl.get().getLocalPlayer(); Vector3 playerStartPosition = Vector3.zero; local_player.transform.position = playerStartPosition + PartyControl.get().getPositionOffset(local_player.control.global_index); for (int i = 0; i < PartyControl.get().getFriendCount(); i++) { chrBehaviorPlayer friend = PartyControl.get().getFriend(i); friend.control.cmdSetPositionAnon(playerStartPosition + PartyControl.get().getPositionOffset(friend.control.global_index)); } party_control.setCurrentRoom(room); // ボスの作成. chrControllerEnemyBase enemy; if (UsesHumanControlForBoss) { enemy = CharacterRoot.get().createEnemy("Boss1", "chrControllerEnemyBoss", "chrBehaviorEnemyBoss_Human") as chrControllerEnemyBase; } else { enemy = CharacterRoot.get().createEnemy("Boss1", "chrControllerEnemyBoss", "chrBehaviorEnemyBoss") as chrControllerEnemyBase; } enemy.cmdSetPosition(new Vector3(0.0f, 0.0f, 20.0f)); // 스테이터스 창. Navi.get().createStatusWindows(); }
public void NotifyFinishedQuickAttack() { indexOfTargets = (indexOfTargets + 1) % targetPlayers.Count; focus = targetPlayers[indexOfTargets]; this.next_step = STEP.MOVE; }
public override void initialize() { this.player = PartyControl.get().getLocalPlayer(); this.player_weapon = this.player.gameObject.findDescendant("anim_wepon"); this.data = GameObject.Find("EventDataIceAtari").GetComponent<EventDataIceAtari>(); // 당첨의 막대 모델. this.ice_bar = this.data.prefab_ice_atari_bar.instantiate(); this.ice_bar.setParent(this.player.gameObject.findDescendant("anim_wrist_R")); this.ice_bar.setLocalPosition(new Vector3(-0.056f, -0.086f, 0.039f)); this.ice_bar.SetActive(false); // "!" 말풍선. this.sprite_bikkuri = Sprite2DRoot.get().createSprite(this.data.texture_bikkuri, true); this.sprite_bikkuri.setVisible(false); // 당첨 말풍선. this.sprite_atari = Sprite2DRoot.get().createSprite(this.data.texture_atari, true); this.sprite_atari.setPosition(new Vector2(0.0f, 150.0f)); this.sprite_atari.setVisible(false); this.sprite_ice_bar = Sprite2DRoot.get().createSprite(this.data.texture_ice_bar, true); this.sprite_ice_bar.setVisible(false); this.sprite_ice_bar.setMaterial(this.data.material_ice_sprite); this.spline = this.data.gameObject.findDescendant("spline_ice").GetComponent<SimpleSplineObject>(); this.tracer.attach(this.spline.curve); }
//======================================================================== // 컨트롤로로부터 메시징된 액션 종료 통지(AI힌트). public void NotifyFinishedCharging() { // 돌진 공격의 대상인 인덱스의 다음 인덱스의 캐릭터에 포커스. indexOfTargets = (indexOfTargets + 1) % targetPlayers.Count; focus = targetPlayers[indexOfTargets]; this.next_step = STEP.MOVE; }
// 작지할 장소 캐릭터마다 다르다. protected Vector3 calc_landing_position(chrBehaviorPlayer player) { Vector3 position = Vector3.zero; position = PartyControl.get().getPositionOffset(player.control.global_index); position = Quaternion.AngleAxis(this.door_dir_to_y_angle(this.door.door_dir), Vector3.up) * position; return(position); }
// 자신 이외의 멤버 가져오기. public chrBehaviorPlayer getFriend(int friend_index) { chrBehaviorPlayer friend = null; if (0 <= friend_index && friend_index < this.players.Count - 1) { friend = this.players[friend_index + 1]; } return(friend); }
// 이벤트 시작. public override void start() { this.player = PartyControl.get().getLocalPlayer(); this.player.beginOuterControll(); this.kabu_san = CharacterRoot.get().findCharacter <chrBehaviorKabu>("NPC_Kabu_San"); CameraControl.get().beginOuterControll(); this.step.set_next(STEP.START); }
// 이벤트 시작. public override void start() { this.player = PartyControl.get().getLocalPlayer(); this.player.beginOuterControll(); this.kabu_san = CharacterRoot.get().findCharacter<chrBehaviorKabu>("NPC_Kabu_San"); CameraControl.get().beginOuterControll(); this.step.set_next(STEP.START); }
// ================================================================ // // 공격할 플레이어를 선택한다. public chrBehaviorPlayer selectTargetPlayer(float distance_limit, float angle_limit) { chrBehaviorPlayer target = null; // 공격 가능 범위에서 가장 가깝고 정면에 있는 플레이어를. // 찾는다. var players = PartyControl.get().getPlayers(); float min_score = -1.0f; foreach (var player in players) { // 거리를 조사한다. float distance = (this.control.getPosition() - player.control.getPosition()).Y(0.0f).magnitude; if (distance >= distance_limit) { continue; } // 정면에서 어느 정도 방향이 어긋나는가?. float angle = MathUtility.calcDirection(this.control.getPosition(), player.control.getPosition()); angle = Mathf.Abs(MathUtility.snormDegree(angle - this.control.getDirection())); if (angle >= angle_limit) { continue; } // float score = distance * MathUtility.remap(0.0f, angle_limit, angle, 1.0f, 2.0f); if (target == null) { target = player; min_score = score; } else { if (score < min_score) { target = player; min_score = score; } } } return(target); }
// 아이템을 사용해 주었을 때(동료가 자신에게) 호출된다. public virtual void onUseItemByFriend(Item.Favor favor, chrBehaviorPlayer friend) { switch (favor.category) { case Item.CATEGORY.SODA_ICE: { this.skin_color_control.startHealing(); } break; } }
//======================================================================== // 보스가 싸우는 플레이어 리스트를 가져온다. protected void initializeTargetPlayers() { // 계정 이름으로 ABC순으로 정렬해 둔다. targetPlayers = new List <chrBehaviorPlayer>(PartyControl.getInstance().getPlayers()); targetPlayers.Sort((a, b) => string.CompareOrdinal(a.name, b.name)); indexOfTargets = 0; // 노릴 플레이어를 결정한다. ABC 정렬 전의 선두 계정 이름을 가진 플레이어가 최초의 표적이 된다. focus = targetPlayers[indexOfTargets]; }
public void dropKey(string key_id, string account_name) { chrBehaviorPlayer player = getPlayerWithAccountName(account_name); if (player == null) { return; } if (has_key.ContainsKey(key_id)) { has_key.Remove(key_id); } }
// 네트 플레이어 삭제. public void deleteNetPlayer(int account_global_index) { do { chrBehaviorPlayer friend = this.getFriendByGlobalIndex(account_global_index); if (friend == null) { break; } this.players.Remove(friend); GameObject.Destroy(friend.gameObject); } while(false); }
protected void decideNextStep() { if (m_isHost) { // 가까이에 있는(퀵 공격 할 수 있는) 플레이어를 찾는다. chrBehaviorPlayer target = this.find_close_player(); if (target != null) { this.next_step = STEP.ACTION; EnemyRoot.getInstance().RequestBossQuickAttack(target.getAcountID(), 1.0f); } else { // FIXME: 통신에 대응시킬 것. float randomValue = Random.value * 4; if (randomValue < 1.0f) { Debug.Log("DirectAttack"); this.next_step = STEP.ACTION; EnemyRoot.getInstance().RequestBossDirectAttack(focus.getAcountID(), 1.0f); } else if (randomValue < 2.0f) { Debug.Log("RangeAttack"); this.next_step = STEP.ACTION; EnemyRoot.getInstance().RequestBossRangeAttack(1.0f, 5.0f); } else { this.next_step = STEP.MOVE; } } } else { this.next_step = STEP.MOVE; } // ---------------------------------------------------------------- // // 캐릭터 좌표를 보낸다. sendCharacterCoordinates(); }
// ================================================================ // // 파워 업 중?. protected bool isBoosted() { bool is_boosted = false; do { chrBehaviorPlayer behavior = this.player.behavior as chrBehaviorPlayer; if (behavior == null) { break; } is_boosted = behavior.isShotBoosted(); } while(false); return(is_boosted); }
// 플레이어가 열쇠를 들었다. public void pickKey(string key_name, string account_name) { chrBehaviorPlayer player = getPlayerWithAccountName(account_name); if (player == null) { return; } string[] key_str = key_name.Split('_'); string key_id = key_str[0]; if (has_key.ContainsKey(key_id) == false) { has_key.Add(key_id, player.control.local_index); } else { has_key[key_id] = player.control.local_index; } }
/** * 퀵 공격한다. * @param targetName 돌격 대상 플레이어 캐릭터 이름. * @param attackPower 대미지에 걸리는 계수. */ public void cmdBossQuickAttack(string target_account_name, float attack_power) { do { if (this.state != chrControllerEnemyBase.EnemyState.MAIN) { break; } chrBehaviorPlayer charge_target_player = PartyControl.getInstance().getPlayerWithAccountName(target_account_name); if (charge_target_player == null) { // 발생하지 않아야 하지만.... Debug.LogError("Can't find the player to attack directly."); break; } this.PlayQuickAttack(charge_target_player.gameObject, attack_power); } while(false); }
// 자신 이외의 파티 멤버를 글로벌 인덱스로 가져오기. public chrBehaviorPlayer getFriendByGlobalIndex(int friend_global_index) { chrBehaviorPlayer friend = null; foreach (var player in this.players) { if ((player as chrBehaviorLocal) != null) { continue; } if (player.control.global_index != friend_global_index) { continue; } friend = player; break; } return(friend); }
void OnCollisionStay(Collision other) { switch (other.gameObject.tag) { case "Player": { chrBehaviorPlayer player = other.gameObject.GetComponent <chrBehaviorPlayer>(); if (player != null) { CollisionResult result = new CollisionResult(); result.object0 = this.gameObject; result.object1 = other.gameObject; result.is_trigger = false; this.collision_results.Add(result); } } break; } }
// 留??꾨젅???ㅽ뻾. public void execute() { // 議곌툑 ??쾶 紐⑥뀡 ?쒖옉. if (this.player.step.is_acrossing_time(use_motion_delay)) { this.player.control.cmdSetMotion("m004_use", 1); } // ?뚮? ?꾨줈 ?щ┛ ??대컢???꾩씠???④낵 ?곸슜. if (this.player.step.is_acrossing_time(heal_effect_delay)) { switch (this.item_favor.category) { case Item.CATEGORY.SODA_ICE: { this.player.control.vital.healFull(); this.player.skin_color_control.startHealing(); // 媛源뚯씠???덈뜕 ?숇즺??泥대젰 ?뚮났. for (int i = 0; i < PartyControl.get().getFriendCount(); i++) { chrBehaviorPlayer friend = PartyControl.get().getFriend(i); float distance = (friend.control.getPosition() - this.player.control.getPosition()).magnitude; if (distance > chrBehaviorPlayer.CHARITY_SPHERE_RADIUS) { continue; } this.player.control.cmdUseItemToFriend(this.item_favor, friend.control.global_index, true); } } break; } } }
// 매 프레임 실행. public void execute() { // 조금 늦게 모션 시작. if (this.player.step.is_acrossing_time(use_motion_delay)) { this.player.control.cmdSetMotion("m004_use", 1); } // 파를 위로 올린 타이밍에 아이템 효과 적용. if (this.player.step.is_acrossing_time(heal_effect_delay)) { switch (this.item_favor.category) { case Item.CATEGORY.SODA_ICE: { this.player.control.vital.healFull(); this.player.skin_color_control.startHealing(); // 가까이에 있던 동료도 체력 회복. for (int i = 0; i < PartyControl.get().getFriendCount(); i++) { chrBehaviorPlayer friend = PartyControl.get().getFriend(i); float distance = (friend.control.getPosition() - this.player.control.getPosition()).magnitude; if (distance > chrBehaviorPlayer.CHARITY_SPHERE_RADIUS) { continue; } this.player.control.cmdUseItemToFriend(this.item_favor, friend.control.global_index, true); } } break; } } }
// ================================================================ // protected void disconnect_event() { if (GlobalParam.get().is_in_my_home == false && GlobalParam.get().is_remote_in_my_home == false) { chrBehaviorPlayer player = this.net_player.behavior as chrBehaviorPlayer; if (player != null) { if (!player.isNowHouseMoving()) { HouseMoveStartEvent start_event = EventRoot.get().startEvent <HouseMoveStartEvent>(); start_event.setPrincipal(player); start_event.setHouse(CharacterRoot.get().findCharacter <chrBehaviorNPC_House>("House1")); } } } else if (GlobalParam.get().is_in_my_home&& GlobalParam.get().is_remote_in_my_home) { this.step.set_next(STEP.BYEBYE); } }
// ================================================================ // // 주역이 될 플레이어(로컬/리모트)를 설정합니다. public void setPrincipal(chrBehaviorPlayer player) { this.player = player; }
public override void execute() { chrBehaviorEnemy mine = this.behavior; BasicAction basic_action = mine.basic_action; float distance_limit = 10.0f; float angle_limit = 45.0f; if (this.finish_child()) { this.step.set_next(STEP.READY); } // ---------------------------------------------------------------- // // 다음 상태로 전환할지 체크합니다. switch (this.step.do_transition()) { case STEP.READY: { // 공격 가능 범위에서 가장 가까이 정면에 있는 플레이어를. // 찾습니다. this.target_player = this.behavior.selectTargetPlayer(distance_limit, angle_limit); if (target_player != null) { this.step.set_next(STEP.TURN); } } break; // 목표 방향으로 선회. case STEP.TURN: { if (this.target_player == null) { this.step.set_next(STEP.READY); } else { basic_action.move_dir = MathUtility.calcDirection(mine.control.getPosition(), this.target_player.control.getPosition()); float dir_diff = MathUtility.snormDegree(basic_action.move_dir - mine.control.getDirection()); if (Mathf.Abs(dir_diff) < 5.0f) { this.push(this.shoot); this.step.sleep(); } } } break; } // ---------------------------------------------------------------- // // 상태가 전환됐을 때의 초기화. while (this.step.get_next() != STEP.NONE) { switch (this.step.do_initialize()) { // 목표 방향으로 선회. case STEP.TURN: { } break; case STEP.FINISH: { this.is_finished = true; } break; } } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. switch (this.step.do_execution(Time.deltaTime)) { // 목표 방향으로 선회. case STEP.TURN: { basic_action.move_dir = MathUtility.calcDirection(mine.control.getPosition(), this.target_player.control.getPosition()); } break; } // ---------------------------------------------------------------- // this.execute_child(); }
public override void execute() { chrBehaviorEnemy mine = this.behavior; BasicAction basic_action = mine.basic_action; if (this.finish_child()) { this.step.set_next(STEP.MOVE); } chrBehaviorPlayer target_player = this.behavior.selectTargetPlayer(float.MaxValue, float.MaxValue); this.melee_attack.target_player = target_player; // ---------------------------------------------------------------- // // 다음 상태로 이동하는지 체크합니다. switch (this.step.do_transition()) { // 걷는 중. case STEP.MOVE: { do { if (target_player == null) { break; } if (!this.behavior.isInAttackRange(target_player.control)) { break; } // this.push(this.melee_attack); this.step.sleep(); } while(false); } break; // 멈춰 있다. case STEP.REST: { if (this.step.get_time() > 1.0f) { this.step.set_next(STEP.MOVE); } do { if (target_player == null) { break; } if (!this.behavior.isInAttackRange(target_player.control)) { break; } // this.push(this.melee_attack); this.step.sleep(); } while(false); } break; } // ---------------------------------------------------------------- // // 상태가 전환됐을 때의 초기화. while (this.step.get_next() != STEP.NONE) { switch (this.step.do_initialize()) { // 걷는 중. case STEP.MOVE: { } break; } } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. switch (this.step.do_execution(Time.deltaTime)) { // 걷는 중. case STEP.MOVE: { do { if (target_player == null) { break; } basic_action.move_dir = MathUtility.calcDirection(mine.control.getPosition(), target_player.control.getPosition()); basic_action.setMoveMotionSpeed(1.0f); basic_action.setMoveSpeed(0.6f); basic_action.setMotionPlaySpeed(0.6f); basic_action.executeMove(); } while(false); } break; // 멈춰있다. case STEP.REST: { basic_action.setMoveMotionSpeed(0.0f); } break; } this.spring.execute(Time.deltaTime); if (this.spring.isMoving()) { this.scale = Mathf.InverseLerp(-1.0f, 1.0f, this.spring.position); this.scale = Mathf.Lerp(1.0f, 2.0f, this.scale); } this.control.transform.localScale = Vector3.one * this.scale; // ---------------------------------------------------------------- // this.execute_child(); if (this.child == this.melee_attack) { this.attack_motion_speed_control(); } }
public override void execute() { chrBehaviorEnemy mine = this.behavior; BasicAction basic_action = mine.basic_action; if (this.finish_child()) { this.step.set_next(STEP.MOVE); } chrBehaviorPlayer target_player = this.behavior.selectTargetPlayer(float.MaxValue, float.MaxValue); this.melee_attack.target_player = target_player; // ---------------------------------------------------------------- // // 다음 상태로 전환할지 체크합니다. switch (this.step.do_transition()) { // 걷는 중. case STEP.MOVE: { do { if (target_player == null) { break; } if (!this.behavior.isInAttackRange(target_player.control)) { break; } // this.push(this.melee_attack); this.step.sleep(); } while(false); } break; // 멈춤. case STEP.REST: { if (this.step.get_time() > 1.0f) { this.step.set_next(STEP.MOVE); } do { if (target_player == null) { break; } if (!this.behavior.isInAttackRange(target_player.control)) { break; } // this.push(this.melee_attack); this.step.sleep(); } while(false); } break; } // ---------------------------------------------------------------- // // 상태가 전한됐을 때의 초기화. while (this.step.get_next() != STEP.NONE) { switch (this.step.do_initialize()) { // 걷는 중. case STEP.MOVE: { } break; } } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. switch (this.step.do_execution(Time.deltaTime)) { // 걷는 중. case STEP.MOVE: { do { if (target_player == null) { break; } basic_action.move_dir = MathUtility.calcDirection(mine.control.getPosition(), target_player.control.getPosition()); basic_action.executeMove(); basic_action.setMoveMotionSpeed(1.0f); } while(false); } break; // 멈춤. case STEP.REST: { basic_action.setMoveMotionSpeed(0.0f); } break; } // ---------------------------------------------------------------- // this.execute_child(); }
public override void execute() { CameraControl camera = CameraControl.get(); // ---------------------------------------------------------------- // // 다음 상태로 이동할지 체크합니다. switch(this.step.do_transition()) { // 이벤트 시작. case STEP.START: { this.step.set_next(STEP.OPEN_DOOR); //camera.module.parallelMoveTo(this.get_locator_position("cam_loc_0")); Debug.Log("Name:" + this.player.controll.account_name); foreach (ItemManager.ItemState istate in GlobalParam.get().item_table.Values) { Debug.Log("Item:" + istate.item_id + " Own:" + istate.owner + " State:" + istate.state); if (istate.owner == this.player.controll.account_name && istate.state == ItemController.State.Picked) { // 이미 아이템을 획득했다면 가지고 갈 수 있게 합니다. ItemManager.get().activeItme(istate.item_id, true); ItemManager.get().finishGrowingItem(istate.item_id); QueryItemPick query = this.player.controll.cmdItemQueryPick(istate.item_id, false, true); if (query != null) { query.is_anon = true; query.set_done(true); query.set_success(true); } ItemManager.get().setVisible(istate.item_id, true); } } // 리모트에서 이사 중은 로컬도 이사합니다. do { MovingData moving = GlobalParam.get().remote_moving; if(!moving.moving) { break; } chrController remote = CharacterRoot.get().findCharacter(moving.characterId); if(remote == null) { break; } chrBehaviorNet remote_player = remote.behavior as chrBehaviorNet; if(remote_player == null) { break; } chrBehaviorNPC_House house = CharacterRoot.getInstance().findCharacter<chrBehaviorNPC_House>(moving.houseId); if(house == null) { break; } Debug.Log("House move event call:" + moving.characterId + ":" + moving.houseId); remote_player.beginHouseMove(house); // '이사중~' 말풍선 표시. house.startHouseMove(); } while(false); } break; // 배추가 옆으로 움직이고 & 대야를 타고 플레이어가 등장. case STEP.OPEN_DOOR: { if(this.hakusai_fcurve.isDone() && this.tarai_fcurve.isDone()) { this.step.set_next(STEP.GET_OFF_TARAI_0); } } break; // 대야에서 내립니다(기슭으로 점프). case STEP.GET_OFF_TARAI_0: { if(!this.player_jump.isMoving()) { this.step.set_next(STEP.GET_OFF_TARAI_1); } } break; // 대야에서 내립니다(조금 걷기). case STEP.GET_OFF_TARAI_1: { if(!this.player_move.isMoving()) { this.step.set_next(STEP.CLOSE_DOOR); } } break; // 배추가 돌아오고 & 대야가 밖으로 이동. case STEP.CLOSE_DOOR: { if(this.hakusai_fcurve.isDone() && this.tarai_fcurve.isDone()) { this.step.set_next(STEP.END); } } break; case STEP.END: { camera.module.popPosture(); this.step.set_next(STEP.IDLE); } break; } // ---------------------------------------------------------------- // // 상태가 전환됐을 때의 초기화. while(this.step.get_next() != STEP.NONE) { dbwin.console().print(this.step.ToString()); switch(this.step.do_initialize()) { // 이벤트 시작. case STEP.START: { camera.module.pushPosture(); this.player.beginOuterControll(); this.player.controll.cmdSetPosition(this.tarai_leave_spline.curve.cvs.back().position); this.tarai_fune.transform.position = this.tarai_leave_spline.curve.cvs.back().position; if(!this.is_local_player) { SoundManager.get().playSE(Sound.ID.SMN_JINGLE01); } } break; // 배추가 옆으로 이동하고 & 대야를 타고 플레이어가 등장. case STEP.OPEN_DOOR: { this.hakusai_set.setControl(true); this.hakusai_fcurve.setSlopeAngle(10.0f, 10.0f); this.hakusai_fcurve.setDuration(4.0f); this.hakusai_fcurve.start(); this.hakusai_tracer.restart(); this.tarai_fcurve.setSlopeAngle(60.0f, 5.0f); this.tarai_fcurve.setDuration(3.5f); this.tarai_fcurve.setDelay(0.5f); this.tarai_fcurve.start(); } break; // 대야에서 내립니다(기슭으로 점프). case STEP.GET_OFF_TARAI_0: { Vector3 start = this.player.controll.getPosition(); Vector3 goal = this.get_locator_position("chr_loc_0"); this.player_jump.start(start, goal, 1.0f); } break; // 대야에서 내립니다(조금 걷기). case STEP.GET_OFF_TARAI_1: { this.player_move.position.start = this.player.controll.getPosition(); this.player_move.position.goal = this.get_locator_position("chr_loc_1"); this.player_move.startConstantVelocity(chrBehaviorLocal.MOVE_SPEED); } break; // 배추가 돌아오고 & 대야가 밖으로 이동. case STEP.CLOSE_DOOR: { this.hakusai_fcurve.setSlopeAngle(10.0f, 10.0f); this.hakusai_fcurve.setDuration(4.0f); this.hakusai_fcurve.setDelay(1.0f); this.hakusai_fcurve.start(); this.hakusai_tracer.restart(); this.hakusai_tracer.setCurrentByDistance(this.hakusai_tracer.curve.calcTotalDistance()); this.tarai_tracer.attach(this.tarai_enter_spline.curve); this.tarai_tracer.restart(); this.tarai_fcurve.reset(); this.tarai_fcurve.setSlopeAngle(10.0f, 60.0f); this.tarai_fcurve.setDuration(2.5f); this.tarai_fcurve.start(); this.ripple_effect.is_created = false; } break; case STEP.END: { // 이벤트 종료. this.hakusai_set.reset(); this.hakusai_set.setControl(false); this.player.endOuterControll(); this.player = null; } break; } } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. switch(this.step.do_execution(Time.deltaTime)) { // 배추가 옆으로 움직인다 & 대야를 타고 플레이어가 등장.. case STEP.OPEN_DOOR: { this.hakusai_fcurve.execute(Time.deltaTime); this.hakusai_tracer.proceedToDistance(this.hakusai_tracer.curve.calcTotalDistance()*this.hakusai_fcurve.getValue()); this.hakusai_set.setPosition(this.hakusai_tracer.cv.position); this.tarai_fcurve.execute(Time.deltaTime); this.tarai_tracer.proceedToDistance(this.tarai_tracer.curve.calcTotalDistance()*(1.0f - this.tarai_fcurve.getValue())); SimpleSpline.ControlVertex cv = this.tarai_tracer.getCurrent(); this.tarai_fune.setPosition(cv.position); this.player.controll.cmdSetPosition(cv.position); this.player.controll.cmdSmoothHeadingTo(cv.position - cv.tangent.Y(0.0f)); if(this.tarai_fcurve.isTriggerDone()) { this.ripple_effect.is_created = false; } } break; // 대야에서 내립니다(기슭을 향해 점프). case STEP.GET_OFF_TARAI_0: { this.player_jump.execute(Time.deltaTime); this.player.controll.cmdSetPosition(this.player_jump.position); this.player.controll.cmdSmoothHeadingTo(this.player_jump.goal); } break; // 대야에서 내립니다(조금 걷는다). case STEP.GET_OFF_TARAI_1: { this.player_move.execute(Time.deltaTime); this.player.controll.cmdSetPosition(this.player_move.position.current); this.player.controll.cmdSmoothHeadingTo(this.player_move.position.goal); this.player.playWalkMotion(); } break; // 배추가 돌아옵니다 & 대야가 밖으로 이동. case STEP.CLOSE_DOOR: { this.hakusai_fcurve.execute(Time.deltaTime); this.hakusai_tracer.proceedToDistance(this.hakusai_tracer.curve.calcTotalDistance()*(1.0f - this.hakusai_fcurve.getValue())); this.hakusai_set.setPosition(this.hakusai_tracer.getCurrent().position); this.tarai_fcurve.execute(Time.deltaTime); this.tarai_tracer.proceedToDistance(this.tarai_tracer.curve.calcTotalDistance()*(1.0f - this.tarai_fcurve.getValue())); this.tarai_fune.transform.position = this.tarai_tracer.getCurrent().position; this.player.stopWalkMotion(); } break; } // 대야 뒤에 나오는 물결. if(!this.ripple_effect.is_created || Vector3.Distance(this.ripple_effect.last_position, this.tarai_fune.getPosition()) > 2.0f) { this.ripple_effect.is_created = true; this.ripple_effect.last_position = this.tarai_fune.transform.position; EffectRoot.get().createRipple(this.ripple_effect.last_position); } // ---------------------------------------------------------------- // }
// 自分が近接攻撃. public override void onMeleeAttack(chrBehaviorPlayer player) { // プレイヤーと接触したら消滅する(テスト用). this.causeVanish(); }
// 작지할 장소 캐릭터마다 다르다. protected Vector3 calc_landing_position(chrBehaviorPlayer player) { Vector3 position = Vector3.zero; position = PartyControl.get().getPositionOffset(player.control.global_index); position = Quaternion.AngleAxis(this.door_dir_to_y_angle(this.door.door_dir), Vector3.up)*position; return(position); }
// 아이템을 사용해 주었을 때(동료가 자신에게) 호출된다. public virtual void onUseItemByFriend(Item.Favor favor, chrBehaviorPlayer friend) { switch(favor.category) { case Item.CATEGORY.SODA_ICE: { this.skin_color_control.startHealing(); } break; } }
public override void execute() { chrBehaviorEnemy mine = this.behavior; BasicAction basic_action = mine.basic_action; float distance_limit = 10.0f; float angle_limit = 45.0f; if(this.finish_child()) { this.step.set_next(STEP.READY); } // ---------------------------------------------------------------- // // 다음 상태로 전환할지 체크합니다. switch(this.step.do_transition()) { case STEP.READY: { // 공격 가능 범위에서 가장 가까이 정면에 있는 플레이어를. // 찾습니다. this.target_player = this.behavior.selectTargetPlayer(distance_limit, angle_limit); if(target_player != null) { this.step.set_next(STEP.TURN); } } break; // 목표 방향으로 선회. case STEP.TURN: { if(this.target_player == null) { this.step.set_next(STEP.READY); } else { basic_action.move_dir = MathUtility.calcDirection(mine.control.getPosition(), this.target_player.control.getPosition()); float dir_diff = MathUtility.snormDegree(basic_action.move_dir - mine.control.getDirection()); if(Mathf.Abs(dir_diff) < 5.0f) { this.push(this.shoot); this.step.sleep(); } } } break; } // ---------------------------------------------------------------- // // 상태가 전환됐을 때의 초기화. while(this.step.get_next() != STEP.NONE) { switch(this.step.do_initialize()) { // 목표 방향으로 선회. case STEP.TURN: { } break; case STEP.FINISH: { this.is_finished = true; } break; } } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. switch(this.step.do_execution(Time.deltaTime)) { // 목표 방향으로 선회. case STEP.TURN: { basic_action.move_dir = MathUtility.calcDirection(mine.control.getPosition(), this.target_player.control.getPosition()); } break; } // ---------------------------------------------------------------- // this.execute_child(); }
// ================================================================ // // 자신이 근접 공격. public virtual void onMeleeAttack(chrBehaviorPlayer player) { }
public override void execute() { BasicAction basic_action = this.behavior.basic_action; if(this.target_player == null) { this.target_player = PartyControl.get().getLocalPlayer(); } // ---------------------------------------------------------------- // // 다음 상태로 이동할지 체크합니다. switch(this.step.do_transition()) { // 공격 중. case STEP.ATTACK: { if(this.behavior.is_attack_motion_finished) { this.step.set_next_delay(STEP.FINISH, 1.0f); } } break; } // ---------------------------------------------------------------- // // 상태가 바뀌었을 때의 초기화. while(this.step.get_next() != STEP.NONE) { switch(this.step.do_initialize()) { // 공격 중. case STEP.ATTACK: { basic_action.setMoveMotionSpeed(0.0f); basic_action.animator.SetTrigger("Attack"); } break; // 끝. case STEP.FINISH: { this.is_finished = true; } break; } } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. switch(this.step.do_execution(Time.deltaTime)) { // 공격 중. case STEP.ATTACK: { if(this.behavior.is_attack_motion_impact) { if(this.behavior.isInAttackRange(this.target_player.control)) { if(this.target_player.isLocal()) { this.target_player.control.causeDamage(this.behavior.control.vital.getAttackPower(), -1); } else { // 원격 플레이어에게는 대미지를 주지 않는다. } } } basic_action.move_dir = MathUtility.calcDirection(this.behavior.control.getPosition(), this.target_player.control.getPosition()); } break; } // ---------------------------------------------------------------- // }
// ================================================================ // public void create(chrBehaviorPlayer player) { this.player = player; }
public override void execute() { CameraControl camera = CameraControl.get(); // ---------------------------------------------------------------- // // 다음 상태로 이행할지 체크합니다.. switch(this.step.do_transition()) { // 이벤트 시작. case STEP.START: { this.step.set_next(STEP.OPEN_DOOR); //camera.module.parallelMoveTo(this.get_locator_position("cam_loc_0")); // 맵에 연관되지 않은 아이템은 가지고 돌아감. bool isPickingup = false; string current_map = MapCreator.get().getCurrentMapName(); ItemController itemYuzu = ItemManager.get().findItem("Yuzu"); if (itemYuzu != null && itemYuzu.isActive()) { if (current_map != itemYuzu.getProduction()) { // 가지고 돌아기는 아이템이 있었다. this.player.controll.cmdItemQueryPick(itemYuzu.name, true, true); isPickingup = true; } } ItemController itemNegi = ItemManager.get().findItem("Negi"); if (itemNegi != null && itemNegi.isActive()) { if (current_map != itemNegi.getProduction()) { // 가지고 돌아가는 아이템이 있었다. this.player.controll.cmdItemQueryPick(itemNegi.name, true, true); isPickingup = true; } } if (this.player.controll.item_carrier.isCarrying() && isPickingup == false) { ItemController item = this.player.controll.item_carrier.getItem(); if (item.isExportable() == false) { // 가지고 나갈 수 없는 것은 두고 갑니다. QueryItemDrop query_drop = this.player.controll.cmdItemQueryDrop(); query_drop.is_drop_done = true; this.player.controll.cmdItemDrop(this.player.controll.account_name); } } } break; // 배추가 옆으로 움직이고 & 대야가 등장. case STEP.OPEN_DOOR: { if(this.hakusai_fcurve.isDone() && this.tarai_fcurve.isDone()) { this.step.set_next(STEP.RIDE_TARAI_0); } } break; // 대야를 탑니다(기슭까지 걷는다). case STEP.RIDE_TARAI_0: { if(!this.player_move.isMoving()) { this.step.set_next(STEP.RIDE_TARAI_1); } } break; // 대야를 탑니다(대야를 향해 점프). case STEP.RIDE_TARAI_1: { if(!this.player_jump.isMoving()) { this.step.set_next(STEP.CLOSE_DOOR); } } break; // 배추가 돌아오고 & 대야가 밖을 향해 이동. case STEP.CLOSE_DOOR: { if(this.hakusai_fcurve.isDone() && this.tarai_fcurve.isDone()) { this.step.set_next(STEP.END); } } break; case STEP.END: { camera.module.popPosture(); this.step.set_next(STEP.IDLE); } break; } // ---------------------------------------------------------------- // // 상태가 전환할 때의 초기화. while(this.step.get_next() != STEP.NONE) { dbwin.console().print(this.step.ToString()); switch(this.step.do_initialize()) { // 이벤트 시작. case STEP.START: { camera.module.pushPosture(); this.player.beginOuterControll(); this.tarai_fune.transform.position = this.tarai_enter_spline.curve.cvs.front().position; } break; // 배추가 옆으로 움직이고 & 대야가 등장. case STEP.OPEN_DOOR: { this.hakusai_set.setControl(true); this.hakusai_fcurve.setSlopeAngle(10.0f, 10.0f); this.hakusai_fcurve.setDuration(4.0f); this.hakusai_fcurve.start(); this.hakusai_tracer.restart(); this.tarai_fcurve.setSlopeAngle(60.0f, 10.0f); this.tarai_fcurve.setDuration(2.0f); this.tarai_fcurve.setDelay(2.0f); this.tarai_fcurve.start(); } break; // 대야를 탑니다(기슭까지 걷는다). case STEP.RIDE_TARAI_0: { this.player_move.position.start = this.player.controll.getPosition(); this.player_move.position.goal = this.get_locator_position("chr_loc_0"); this.player_move.startConstantVelocity(chrBehaviorLocal.MOVE_SPEED); } break; // 대야를 탑니다(대야를 향해서 점프). case STEP.RIDE_TARAI_1: { Vector3 start = this.player.controll.getPosition(); Vector3 goal = this.tarai_enter_spline.curve.cvs.back().position; this.player_jump.start(start, goal, 1.0f); } break; // 배추가 돌아오고 & 대야가 밖을 향해 이동. case STEP.CLOSE_DOOR: { this.hakusai_fcurve.setSlopeAngle(10.0f, 10.0f); this.hakusai_fcurve.setDuration(4.0f); this.hakusai_fcurve.start(); this.hakusai_tracer.restart(); this.hakusai_tracer.setCurrentByDistance(this.hakusai_tracer.curve.calcTotalDistance()); this.tarai_tracer.attach(this.tarai_leave_spline.curve); this.tarai_tracer.restart(); this.tarai_fcurve.reset(); this.tarai_fcurve.setSlopeAngle(20.0f, 60.0f); this.tarai_fcurve.setDuration(2.0f); this.tarai_fcurve.start(); } break; case STEP.END: { // 이벤트 종료. this.hakusai_set.reset(); this.hakusai_set.setControl(false); if(this.is_local_player) { if(this.is_map_change) { GlobalParam.get().skip_enter_event = false; GlobalParam.get().fadein_start = false; if(GlobalParam.get().is_in_my_home) { GameRoot.get().step.set_next(GameRoot.STEP.VISIT); } else { GameRoot.get().step.set_next(GameRoot.STEP.GO_HOME); } // 정원 이동을 알림. if (GlobalParam.get().request_move_home) { Debug.Log("NotifyFieldMoving Leave END."); GameRoot.get().NotifyFieldMoving(); } } else { GlobalParam.get().is_in_my_home = !GlobalParam.get().is_in_my_home; this.player.controll.cmdSetPosition(this.initial_player_position); this.player.endOuterControll(); } } else { // 아이템을 비활성화하고 나서 드롭하지 않으면 재생합니다. ItemBehaviorFruit fruit = this.player.controll.getCarriedItem<ItemBehaviorFruit>(); if(fruit != null) { fruit.activeItem(false); } // 맵 이동이 없을 때 아이템을 가지고 돌아온 경우 아이템의 게임 오브젝트를. // 폐기하지 않게 하고자 아이템을 버립니다. this.player.controll.cmdItemDrop(this.player.name); CharacterRoot.get().deletaCharacter(this.player.controll); } this.player = null; } break; } } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. switch(this.step.do_execution(Time.deltaTime)) { // 배추가 옆으로 움직이고 & 대야가 등장. case STEP.OPEN_DOOR: { this.hakusai_fcurve.execute(Time.deltaTime); this.hakusai_tracer.proceedToDistance(this.hakusai_tracer.curve.calcTotalDistance()*this.hakusai_fcurve.getValue()); this.hakusai_set.setPosition(this.hakusai_tracer.getCurrent().position); this.tarai_fcurve.execute(Time.deltaTime); this.tarai_tracer.proceedToDistance(this.tarai_tracer.curve.calcTotalDistance()*this.tarai_fcurve.getValue()); this.tarai_fune.setPosition(this.tarai_tracer.getCurrent().position); if(this.tarai_fcurve.isTriggerDone()) { this.ripple_effect.is_created = false; } } break; // 대야를 탑니다(기슭까지 걷는다). case STEP.RIDE_TARAI_0: { this.player_move.execute(Time.deltaTime); this.player.controll.cmdSetPosition(this.player_move.position.current); this.player.controll.cmdSmoothHeadingTo(this.player_move.position.goal); this.player.playWalkMotion(); } break; // 대야를 탑니다(대야를 향해서 점프). case STEP.RIDE_TARAI_1: { this.player_jump.execute(Time.deltaTime); this.player.controll.cmdSetPosition(this.player_jump.position); this.player.controll.cmdSmoothHeadingTo(this.player_jump.goal); this.player.stopWalkMotion(); if(this.player_jump.is_trigger_bounce && this.player_jump.bounce_count == 1) { this.ripple_effect.is_created = false; } } break; // 배추가 돌아오고 & 대야가 밖을 향해 이동. case STEP.CLOSE_DOOR: { this.hakusai_fcurve.execute(Time.deltaTime); this.hakusai_tracer.proceedToDistance(this.hakusai_tracer.curve.calcTotalDistance()*(1.0f - this.hakusai_fcurve.getValue())); this.hakusai_set.setPosition(this.hakusai_tracer.cv.position); this.tarai_fcurve.execute(Time.deltaTime); this.tarai_tracer.proceedToDistance(this.tarai_tracer.curve.calcTotalDistance()*this.tarai_fcurve.getValue()); SimpleSpline.ControlVertex cv = this.tarai_tracer.getCurrent(); this.tarai_fune.setPosition(cv.position); this.player.controll.cmdSetPosition(cv.position); this.player.controll.cmdSmoothHeadingTo(cv.position + cv.tangent.Y(0.0f)); this.player.stopWalkMotion(); } break; } // 대야 뒤에 나오는 물결. if(!this.ripple_effect.is_created || Vector3.Distance(this.ripple_effect.last_position, this.tarai_fune.getPosition()) > 2.0f) { this.ripple_effect.is_created = true; this.ripple_effect.last_position = this.tarai_fune.transform.position; EffectRoot.get().createRipple(this.ripple_effect.last_position); } // ---------------------------------------------------------------- // }
public override void execute() { CameraControl camera = CameraControl.get(); // ---------------------------------------------------------------- // // 다음 상태로 이동할지 체크합니다. switch (this.step.do_transition()) { // 이벤트 시작. case STEP.START: { this.step.set_next(STEP.OPEN_DOOR); //camera.module.parallelMoveTo(this.get_locator_position("cam_loc_0")); Debug.Log("Name:" + this.player.controll.account_name); foreach (ItemManager.ItemState istate in GlobalParam.get().item_table.Values) { Debug.Log("Item:" + istate.item_id + " Own:" + istate.owner + " State:" + istate.state); if (istate.owner == this.player.controll.account_name && istate.state == ItemController.State.Picked) { // 이미 아이템을 획득했다면 가지고 갈 수 있게 합니다. ItemManager.get().activeItme(istate.item_id, true); ItemManager.get().finishGrowingItem(istate.item_id); QueryItemPick query = this.player.controll.cmdItemQueryPick(istate.item_id, false, true); if (query != null) { query.is_anon = true; query.set_done(true); query.set_success(true); } ItemManager.get().setVisible(istate.item_id, true); } } // 리모트에서 이사 중은 로컬도 이사합니다. do { MovingData moving = GlobalParam.get().remote_moving; if (!moving.moving) { break; } chrController remote = CharacterRoot.get().findCharacter(moving.characterId); if (remote == null) { break; } chrBehaviorNet remote_player = remote.behavior as chrBehaviorNet; if (remote_player == null) { break; } chrBehaviorNPC_House house = CharacterRoot.getInstance().findCharacter <chrBehaviorNPC_House>(moving.houseId); if (house == null) { break; } Debug.Log("House move event call:" + moving.characterId + ":" + moving.houseId); remote_player.beginHouseMove(house); // '이사중~' 말풍선 표시. house.startHouseMove(); } while(false); } break; // 배추가 옆으로 움직이고 & 대야를 타고 플레이어가 등장. case STEP.OPEN_DOOR: { if (this.hakusai_fcurve.isDone() && this.tarai_fcurve.isDone()) { this.step.set_next(STEP.GET_OFF_TARAI_0); } } break; // 대야에서 내립니다(기슭으로 점프). case STEP.GET_OFF_TARAI_0: { if (!this.player_jump.isMoving()) { this.step.set_next(STEP.GET_OFF_TARAI_1); } } break; // 대야에서 내립니다(조금 걷기). case STEP.GET_OFF_TARAI_1: { if (!this.player_move.isMoving()) { this.step.set_next(STEP.CLOSE_DOOR); } } break; // 배추가 돌아오고 & 대야가 밖으로 이동. case STEP.CLOSE_DOOR: { if (this.hakusai_fcurve.isDone() && this.tarai_fcurve.isDone()) { this.step.set_next(STEP.END); } } break; case STEP.END: { camera.module.popPosture(); this.step.set_next(STEP.IDLE); } break; } // ---------------------------------------------------------------- // // 상태가 전환됐을 때의 초기화. while (this.step.get_next() != STEP.NONE) { dbwin.console().print(this.step.ToString()); switch (this.step.do_initialize()) { // 이벤트 시작. case STEP.START: { camera.module.pushPosture(); this.player.beginOuterControll(); this.player.controll.cmdSetPosition(this.tarai_leave_spline.curve.cvs.back().position); this.tarai_fune.transform.position = this.tarai_leave_spline.curve.cvs.back().position; if (!this.is_local_player) { SoundManager.get().playSE(Sound.ID.SMN_JINGLE01); } } break; // 배추가 옆으로 이동하고 & 대야를 타고 플레이어가 등장. case STEP.OPEN_DOOR: { this.hakusai_set.setControl(true); this.hakusai_fcurve.setSlopeAngle(10.0f, 10.0f); this.hakusai_fcurve.setDuration(4.0f); this.hakusai_fcurve.start(); this.hakusai_tracer.restart(); this.tarai_fcurve.setSlopeAngle(60.0f, 5.0f); this.tarai_fcurve.setDuration(3.5f); this.tarai_fcurve.setDelay(0.5f); this.tarai_fcurve.start(); } break; // 대야에서 내립니다(기슭으로 점프). case STEP.GET_OFF_TARAI_0: { Vector3 start = this.player.controll.getPosition(); Vector3 goal = this.get_locator_position("chr_loc_0"); this.player_jump.start(start, goal, 1.0f); } break; // 대야에서 내립니다(조금 걷기). case STEP.GET_OFF_TARAI_1: { this.player_move.position.start = this.player.controll.getPosition(); this.player_move.position.goal = this.get_locator_position("chr_loc_1"); this.player_move.startConstantVelocity(chrBehaviorLocal.MOVE_SPEED); } break; // 배추가 돌아오고 & 대야가 밖으로 이동. case STEP.CLOSE_DOOR: { this.hakusai_fcurve.setSlopeAngle(10.0f, 10.0f); this.hakusai_fcurve.setDuration(4.0f); this.hakusai_fcurve.setDelay(1.0f); this.hakusai_fcurve.start(); this.hakusai_tracer.restart(); this.hakusai_tracer.setCurrentByDistance(this.hakusai_tracer.curve.calcTotalDistance()); this.tarai_tracer.attach(this.tarai_enter_spline.curve); this.tarai_tracer.restart(); this.tarai_fcurve.reset(); this.tarai_fcurve.setSlopeAngle(10.0f, 60.0f); this.tarai_fcurve.setDuration(2.5f); this.tarai_fcurve.start(); this.ripple_effect.is_created = false; } break; case STEP.END: { // 이벤트 종료. this.hakusai_set.reset(); this.hakusai_set.setControl(false); this.player.endOuterControll(); this.player = null; } break; } } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. switch (this.step.do_execution(Time.deltaTime)) { // 배추가 옆으로 움직인다 & 대야를 타고 플레이어가 등장.. case STEP.OPEN_DOOR: { this.hakusai_fcurve.execute(Time.deltaTime); this.hakusai_tracer.proceedToDistance(this.hakusai_tracer.curve.calcTotalDistance() * this.hakusai_fcurve.getValue()); this.hakusai_set.setPosition(this.hakusai_tracer.cv.position); this.tarai_fcurve.execute(Time.deltaTime); this.tarai_tracer.proceedToDistance(this.tarai_tracer.curve.calcTotalDistance() * (1.0f - this.tarai_fcurve.getValue())); SimpleSpline.ControlVertex cv = this.tarai_tracer.getCurrent(); this.tarai_fune.setPosition(cv.position); this.player.controll.cmdSetPosition(cv.position); this.player.controll.cmdSmoothHeadingTo(cv.position - cv.tangent.Y(0.0f)); if (this.tarai_fcurve.isTriggerDone()) { this.ripple_effect.is_created = false; } } break; // 대야에서 내립니다(기슭을 향해 점프). case STEP.GET_OFF_TARAI_0: { this.player_jump.execute(Time.deltaTime); this.player.controll.cmdSetPosition(this.player_jump.position); this.player.controll.cmdSmoothHeadingTo(this.player_jump.goal); } break; // 대야에서 내립니다(조금 걷는다). case STEP.GET_OFF_TARAI_1: { this.player_move.execute(Time.deltaTime); this.player.controll.cmdSetPosition(this.player_move.position.current); this.player.controll.cmdSmoothHeadingTo(this.player_move.position.goal); this.player.playWalkMotion(); } break; // 배추가 돌아옵니다 & 대야가 밖으로 이동. case STEP.CLOSE_DOOR: { this.hakusai_fcurve.execute(Time.deltaTime); this.hakusai_tracer.proceedToDistance(this.hakusai_tracer.curve.calcTotalDistance() * (1.0f - this.hakusai_fcurve.getValue())); this.hakusai_set.setPosition(this.hakusai_tracer.getCurrent().position); this.tarai_fcurve.execute(Time.deltaTime); this.tarai_tracer.proceedToDistance(this.tarai_tracer.curve.calcTotalDistance() * (1.0f - this.tarai_fcurve.getValue())); this.tarai_fune.transform.position = this.tarai_tracer.getCurrent().position; this.player.stopWalkMotion(); } break; } // 대야 뒤에 나오는 물결. if (!this.ripple_effect.is_created || Vector3.Distance(this.ripple_effect.last_position, this.tarai_fune.getPosition()) > 2.0f) { this.ripple_effect.is_created = true; this.ripple_effect.last_position = this.tarai_fune.transform.position; EffectRoot.get().createRipple(this.ripple_effect.last_position); } // ---------------------------------------------------------------- // }
//======================================================================== // 보스가 싸우는 플레이어 리스트를 가져온다. protected void initializeTargetPlayers() { // 계정 이름으로 ABC순으로 정렬해 둔다. targetPlayers = new List<chrBehaviorPlayer>(PartyControl.getInstance().getPlayers()); targetPlayers.Sort((a, b) => string.CompareOrdinal(a.name, b.name)); indexOfTargets = 0; // 노릴 플레이어를 결정한다. ABC 정렬 전의 선두 계정 이름을 가진 플레이어가 최초의 표적이 된다. focus = targetPlayers[indexOfTargets]; }