// 공격 모션 속도. protected void attack_motion_speed_control() { chrBehaviorEnemy mine = this.behavior; BasicAction basic_action = mine.basic_action; if (this.melee_attack.step.get_current() == MeleeAttackAction.STEP.ATTACK) { float current_time = this.melee_attack.step.get_time(); float furikaburi_time = 0.38f + 0.3f; float play_speed = 0.5f; if (current_time < furikaburi_time) { // 머리 위로 높이 쳐들 때까지 서서히 느리게. float rate = Mathf.Clamp01(Mathf.InverseLerp(0.0f, furikaburi_time, current_time)); play_speed = Mathf.Lerp(0.3f, 0.1f, rate); } else { // 내리 휘두를 때가지 단숨에 빨라진다. float rate = Mathf.Clamp01(Mathf.InverseLerp(furikaburi_time, furikaburi_time + 0.3f, current_time)); play_speed = Mathf.Lerp(0.1f, 0.7f, rate); } basic_action.setMotionPlaySpeed(play_speed); } }
// 대미지양 통지 정보 수신 함수. public void OnReceiveDamageNotifyPacket(int node, PacketId id, byte[] data) { DamageNotifyPacket packet = new DamageNotifyPacket(data); DamageData damage = packet.GetPacket(); #if false string avator_name = ""; AccountData account_data = AccountManager.get().getAccountData(damage.attacker); avator_name = account_data.avator_id; string log = "ReceiveDamageNotifyPacket:" + damage.target + "(" + damage.attacker + ") Damage:" + damage.damage; Debug.Log(log); #endif chrBehaviorEnemy behavior = findCharacter <chrBehaviorEnemy>(damage.target); if (behavior == null) { return; } //log = "Cause damage:" + avator_name + " -> " + damage.target + " Damage:" + damage.damage; //Debug.Log(log); // 캐릭터의 대미지를 반영. behavior.control.causeDamage(damage.damage, damage.attacker, false); }
// 근접 공격이 통했을 때 호출된다. public override void onMeleeAttackHitted(chrBehaviorBase other) { // 근접 공격으로 적을 10마리 쓰러뜨릴 때마다 캔디가 나온다. do { if (other.control.vital.getHitPoint() > 0) { break; } this.melee_count++; if (this.melee_count % 10 != 0) { break; } chrBehaviorEnemy enemy = other as chrBehaviorEnemy; if (enemy == null) { break; } enemy.setRewardItem("candy00", "candy00", null); } while(false); }
// ================================================================ // public override void create(chrBehaviorEnemy behavior, ActionBase.DescBase desc_base = null) { base.create(behavior, desc_base); this.melee_attack = new MeleeAttackAction(); this.melee_attack.create(this.behavior); }
// 적을 펑하고 스폰한다(Action, 게스트용). public void create_enemy_internal_pedigree(string pedigree) { // 등록된 적 중에서 랜덤하게 선택. do { string[] tokens = pedigree.Split('.'); if (tokens.Length < 3) { break; } string enemy_name = tokens[0] + "." + tokens[1]; if (!System.Enum.IsDefined(typeof(Enemy.BEHAVE_KIND), tokens[2])) { break; } Enemy.BEHAVE_KIND behave = (Enemy.BEHAVE_KIND)System.Enum.Parse(typeof(Enemy.BEHAVE_KIND), tokens[2]); chrBehaviorEnemy enemy = LevelControl.get().createCurrentRoomEnemy <chrBehaviorEnemy>(enemy_name); if (enemy == null) { break; } enemy.name = enemy_name; enemy.setBehaveKind(behave, null); enemy.beginSpawn(this.transform.position + Vector3.up * 3.0f, this.transform.forward); } while(false); }
// 적을 펑하고 스폰한다(Action, 호스트용)). public void create_enemy_internal() { // 등록된 적 중에서 랜덤하게 선택. if (this.spawn_enemies.Count == 0) { this.spawn_enemies.Add(new SpawnEnemy()); } float sum = 0.0f; foreach (var se in this.spawn_enemies) { sum += se.frequency; } SpawnEnemy spawn_enemy = this.spawn_enemies[0]; float rand = Random.Range(0.0f, sum); foreach (var se in this.spawn_enemies) { rand -= se.frequency; if (rand <= 0.0f) { spawn_enemy = se; break; } } // dbwin.console().print("Spawn LairName:" + this.name); dbwin.console().print("Create enemy:" + spawn_enemy.enemy_name); //Debug.Log("Spawn LairName:" + this.name); //Debug.Log("Create enemy:" + spawn_enemy.enemy_name); chrBehaviorEnemy enemy = LevelControl.get().createCurrentRoomEnemy <chrBehaviorEnemy>(spawn_enemy.enemy_name); if (enemy != null) { enemy.setBehaveKind(spawn_enemy.behave_kind, spawn_enemy.behave_desc); enemy.beginSpawn(this.transform.position + Vector3.up * 3.0f, this.transform.forward); if (GameRoot.get().isHost()) { // 이 문자열을 함께 게스트에 송신한다. string pedigree = enemy.name + "." + spawn_enemy.behave_kind; // 원격 송신. EnemyRoot.get().RequestSpawnEnemy(this.name, pedigree); //Debug.Log(pedigree); } } }
// ================================================================ // public override void create(chrBehaviorEnemy behavior, ActionBase.DescBase desc_base = null) { base.create(behavior, desc_base); this.melee_attack = new MeleeAttackAction(); this.melee_attack.create(this.behavior); this.model = this.behavior.gameObject.findChildGameObject("model"); }
// 디버그용 모든 적 퇴장. public void debugCauseVanishToAllEnemy() { foreach (var chr in this.enemies) { chrBehaviorEnemy enemy = chr.gameObject.GetComponent <chrBehaviorEnemy>(); if (enemy != null) { enemy.causeVanish(); } } }
public Vector3 outlet_vector = Vector3.forward; // 제네레이터에서 튀어나올 때의 속도. // ================================================================ // // 생성합니다. public override void create(chrBehaviorEnemy behavior, ActionBase.DescBase desc_base = null) { base.create(behavior, desc_base); this.motion_speed.current = 0.0f; this.motion_speed.goal = 0.0f; this.animator = this.behavior.gameObject.GetComponent <Animator>(); this.jump = new ipModule.Jump(); this.jump.gravity *= 3.0f; this.jump.bounciness = new Vector3(1.0f, -0.4f, 1.0f); }
// ================================================================ // public override void create(chrBehaviorEnemy behavior, ActionBase.DescBase desc_base = null) { base.create(behavior, desc_base); this.melee_attack = new MeleeAttackAction(); this.melee_attack.create(this.behavior); this.spring = new ipModule.Spring(); this.spring.k = 300.0f; this.spring.reduce = 0.90f; // 스폰 → 착지 시에 바운드하지 않게 합니다. this.behavior.basic_action.jump.bounciness.y = 0.0f; }
// 적이 그 자리에 멈춰선 상태 해제. public void endStillEnemies(RoomController room_control, float delay) { if (room_control == null) { room_control = PartyControl.get().getCurrentRoom(); } Room room = this.rooms[room_control.getIndex().x, room_control.getIndex().z]; foreach (var chr in room.enemies) { chrBehaviorEnemy enemy = chr.behavior as chrBehaviorEnemy; enemy.endStill(delay); } }
// ================================================================ // public override void create(chrBehaviorEnemy behavior, ActionBase.DescBase desc_base = null) { base.create(behavior, desc_base); Desc desc = desc_base as Desc; if (desc == null) { desc = new Desc(this.control.getPosition()); } this.positions[0] = desc.position0; this.positions[1] = desc.position1; this.melee_attack = new MeleeAttackAction(); this.melee_attack.create(this.behavior); }
// 부모가 실행 중에도 실행. public override void stealth() { chrBehaviorEnemy mine = this.behavior; BasicAction basic_action = mine.basic_action; switch (basic_action.step.get_current()) { case BasicAction.STEP.SPAWN: { if (basic_action.jump.velocity.y < 0.0f) { basic_action.step.set_next(BasicAction.STEP.UNIQUE); } } break; } }
//룸 안에 초기 배치할 적을 만든다. public void createRoomEnemies(RoomController room) { #if true MapCreator map_creater = MapCreator.get(); Vector3 room_position = map_creater.getRoomCenterPosition(room.getIndex()); string room_index = room.getIndex().x.ToString("D1") + room.getIndex().z.ToString("D1"); string item_type, item_name; Room level_room = this.rooms[room.getIndex().x, room.getIndex().z]; level_room.items.Clear(); List <Map.BlockIndex> lair_places = map_creater.getLairPlacesRoom(room.getIndex()); // FieldGenerator가 설정한 랜덤한 위치에 제네레이터를 배치. int n = 0; foreach (var lair_place in lair_places) { string enemy_name = "Enemy_Lair" + "." + room_index + "." + n.ToString("D3"); chrBehaviorEnemy behavior = this.createRoomEnemy <chrBehaviorEnemy>(room, enemy_name); if (behavior == null) { continue; } chrController chr = behavior.control; chrBehaviorEnemy_Lair lair = chr.behavior as chrBehaviorEnemy_Lair; // 쓰러뜨렸을 때 나타날 아이템. object item_option0 = null; if (n == 0) { item_type = "ice00"; // 당첨, 탈락 추첨. item_option0 = this.item_lot.ice_atari.draw(this.rand.getRandom()); } else { item_type = "cake00"; } item_name = item_type + "_" + room_index + "_" + level_room.enter_count + "_" + n.ToString("D2"); lair.setRewardItem(item_type, item_name, item_option0); level_room.items.Add(item_name); // 스폰할 적. chrBehaviorEnemy_Lair.SpawnEnemy spawn; spawn = lair.resisterSpawnEnemy(); spawn.enemy_name = "Enemy_Obake"; spawn.behave_kind = Enemy.BEHAVE_KIND.UROURO; spawn.behave_desc = null; spawn.frequency = 1.0f; spawn = lair.resisterSpawnEnemy(); spawn.enemy_name = "Enemy_Kumasan"; spawn.behave_kind = Enemy.BEHAVE_KIND.TOTUGEKI; spawn.behave_desc = null; spawn.frequency = 0.5f; spawn = lair.resisterSpawnEnemy(); spawn.enemy_name = "Enemy_Obake"; spawn.behave_kind = Enemy.BEHAVE_KIND.WARP_DE_FIRE; spawn.behave_desc = null; spawn.frequency = 0.5f; spawn = lair.resisterSpawnEnemy(); spawn.enemy_name = "Enemy_Kumasan"; spawn.behave_kind = Enemy.BEHAVE_KIND.JUMBO; spawn.behave_desc = null; spawn.frequency = 0.5f; spawn = lair.resisterSpawnEnemy(); spawn.enemy_name = "Enemy_Obake"; spawn.behave_kind = Enemy.BEHAVE_KIND.GOROGORO; spawn.behave_desc = null; spawn.frequency = 0.5f; Vector3 position = map_creater.getBlockCenterPosition(lair_place); lair.control.cmdSetPositionAnon(room_position + position); lair.control.cmdSetDirectionAnon(135.0f); n++; } // 도어 앞에 파수꾼처럼 배치. for (int i = 0; i < (int)Map.EWSN.NUM; i++) { DoorControl door = room.getDoor((Map.EWSN)i); if (door == null) { continue; } string enemy_name = "Enemy_Kumasan" + "." + room_index + "." + i.ToString("D3"); chrBehaviorEnemy enemy = this.createRoomEnemy <chrBehaviorEnemy>(room, enemy_name); Map.RoomIndex ri; Map.BlockIndex bi; map_creater.getBlockIndexFromPosition(out ri, out bi, door.getPosition()); Vector3 position = door.getPosition(); float angle = 0.0f; Map.EWSN eswn = door.door_dir; for (int j = 0; j < 4; j++) { if (map_creater.isPracticable(ri, bi, eswn)) { break; } eswn = Map.eswn.next_cw(eswn); } float offset = 7.0f; switch (eswn) { case Map.EWSN.NORTH: { position += Vector3.forward * offset; angle = 180.0f; } break; case Map.EWSN.SOUTH: { position += Vector3.back * offset; angle = 0.0f; } break; case Map.EWSN.EAST: { position += Vector3.right * offset; angle = 90.0f; } break; case Map.EWSN.WEST: { position += Vector3.left * offset; angle = -90.0f; } break; } enemy.control.cmdSetPositionAnon(position); enemy.control.cmdSetDirectionAnon(angle); var desc = new Character.OufukuAction.Desc(); Vector3 line = Quaternion.AngleAxis(angle, Vector3.up) * Vector3.right; desc.position0 = position + line * 2.0f; desc.position1 = position - line * 2.0f; enemy.setBehaveKind(Enemy.BEHAVE_KIND.OUFUKU, desc); } // 그 자리에서 총을 쏘는 몬스터 / 무기 체인지 아이템. int item_place = this.rand.getRandomInt(level_room.places.Count); int shot_item_sel = this.rand.getRandomInt(10) % 2; for (int i = 0; i < level_room.places.Count; i++) { var place = level_room.places[i]; Vector3 position = room_position + map_creater.getBlockCenterPosition(place); if (i == item_place) { // 무기 체인지 아이템. if (shot_item_sel == 0) { item_type = "shot_negi"; } else { item_type = "shot_yuzu"; } item_name = item_type + "_" + room_index + "_" + level_room.enter_count + "_" + n.ToString("D2"); level_room.items.Add(item_name); ItemManager.get().createItem(item_type, item_name, PartyControl.get().getLocalPlayer().getAcountID()); ItemManager.get().setPositionToItem(item_name, position); } else { // 그 자리에서 총을 쏘는 몬스터. string enemy_name = "Enemy_Obake" + "." + room_index + "." + i.ToString("D3"); chrBehaviorEnemy enemy = this.createRoomEnemy <chrBehaviorEnemy>(room, enemy_name); if (enemy == null) { continue; } enemy.setBehaveKind(Enemy.BEHAVE_KIND.SONOBA_DE_FIRE); enemy.control.cmdSetPositionAnon(position); } } #else #if false chrController chr0 = this.createRoomEnemy <chrBehaviorEnemy>(room, "Enemy_Lair").control; //chrController chr1 = this.createRoomEnemy<chrBehaviorEnemy>(room, "Enemy_Lair").control; chrBehaviorEnemy_Lair lair0 = chr0.behavior as chrBehaviorEnemy_Lair; //chrBehaviorEnemy_Lair lair1 = chr1.behavior as chrBehaviorEnemy_Lair; lair0.name += "00"; //lair0.setRewardItem("cake00", "cake01"); //lair1.setRewardItem("ice00" , "ice01"); chrBehaviorEnemy_Lair.SpawnEnemy spawn; spawn = lair0.resisterSpawnEnemy(); spawn.enemy_name = "Enemy_Kumasan"; spawn.behave_kind = Enemy.BEHAVE_KIND.JUMBO; spawn.behave_desc = null; spawn.frequency = 1.0f; //spawn = lair0.resisterSpawnEnemy(); //spawn.enemy_name = "Enemy_Kumasan"; //spawn.behave_kind = Enemy.BEHAVE_KIND.TOTUGEKI; //spawn.behave_desc = null; //spawn.frequency = 0.5f; //lair0.spawn_enemy.enemy_name = "Enemy_Obake"; //lair0.spawn_enemy.behave_kind = Enemy.BEHAVE_KIND.UROURO; //lair1.spawn_enemy = "Enemy_Obake"; Vector3 player_position = room.gameObject.transform.position; lair0.control.cmdSetPositionAnon(player_position + Vector3.forward * 2.0f); //lair1.control.cmdSetPositionAnon(player_position + Vector3.forward*2.0f + Vector3.right*4.0f); lair0.control.cmdSetDirectionAnon(135.0f); //lair1.control.cmdSetDirectionAnon(135.0f); // if (room.getIndex().x == 2 && room.getIndex().z == 1) { player_position = MapCreator.get().getPlayerStartPosition(); lair0.control.cmdSetPositionAnon(player_position + Vector3.forward * 4.0f); //lair1.control.cmdSetPositionAnon(player_position + Vector3.forward*2.0f + Vector3.right*4.0f); } #else for (int i = 0; i < 2; i++) { chrBehaviorEnemy enemy = this.createRoomEnemy <chrBehaviorEnemy>(room, i == 0 ? "Enemy_Obake" : "Enemy_Kumasan"); //chrController obake = this.createRoomEnemy<chrBehaviorEnemy>(room, "Enemy_Lair").controll; // Vector3 player_position = room.gameObject.transform.position; enemy.control.cmdSetPositionAnon(player_position + Vector3.forward * 3.0f); enemy.control.cmdSetDirectionAnon(180.0f - 45.0f); if (room.getIndex().x == 2 && room.getIndex().z == 1) { player_position = MapCreator.get().getPlayerStartPosition(); enemy.control.cmdSetPositionAnon(player_position + Vector3.forward * 2.0f + Vector3.right * 2.0f * (float)i); } if (i == 0) { //var desc = new Character.OufukuAction.Desc(); //Vector3 line = Quaternion.AngleAxis(180.0f, Vector3.up)*Vector3.back; //desc.position0 = player_position + line*2.0f; //desc.position1 = player_position - line*2.0f; enemy.setBehaveKind(Enemy.BEHAVE_KIND.GOROGORO); break; } else { enemy.setBehaveKind(Enemy.BEHAVE_KIND.TOTUGEKI); } } #endif #endif }
// ================================================================ // // 콜리전의 의미 부여. protected void resolve_collision() { foreach(var result in this.control.collision_results) { if(result.object1 == null) { continue; } //GameObject self = result.object0; GameObject other = result.object1; // 플레이어가 보스의 콜리전에 파뭍혀 움직일 수 없게 되지 않게. // 방의 중심 방향으로 밀어낸다. if(other.tag == "Boss") { if(this.force_push_out(result)) { continue; } } switch(other.tag) { case "Enemy": case "EnemyLair": case "Boss": { do { chrBehaviorEnemy enemy = other.GetComponent<chrBehaviorEnemy>(); if(enemy == null) { break; } if(!this.melee_attack.isInAttackRange(enemy.control)) { //break; } if(this.step.get_current() == STEP.MELEE_ATTACK) { break; } if(!this.melee_attack.isHasInput()) { break; } this.melee_target = enemy; this.step.set_next(STEP.MELEE_ATTACK); } while(false); result.object1 = null; } break; case "Door": { this.cmdNotiryStayDoorBox(other.gameObject.GetComponent<DoorControl>()); } break; case "Item": { do { ItemController item = other.GetComponent<ItemController>(); // 아이템을 주울수있나 조사한다. bool is_pickable = true; switch(item.behavior.item_favor.category) { case Item.CATEGORY.CANDY: { is_pickable = this.item_slot.candy.isVacant(); } break; case Item.CATEGORY.SODA_ICE: case Item.CATEGORY.ETC: { int slot_index = this.item_slot.getEmptyMiscSlot(); // 슬롯이 가득 = 더 가질 수 없을 때. if(slot_index < 0) { is_pickable = false; } } break; case Item.CATEGORY.WEAPON: { // 사용 중인 샷과 같으면 주울 수 없다. SHOT_TYPE shot_type = Item.Weapon.getShotType(item.name); is_pickable = (this.shot_type != shot_type); } break; } if(!is_pickable) { break; } this.control.cmdItemQueryPick(item.name, true, false); } while(false); } break; } } }
public void setTarget(chrBehaviorEnemy target) { this.target = target; }
public Vector3 outlet_vector = Vector3.forward; // 제네레이터에서 튀어나올 때의 속도. // ================================================================ // // 생성합니다. public override void create(chrBehaviorEnemy behavior, ActionBase.DescBase desc_base = null) { base.create(behavior, desc_base); this.motion_speed.current = 0.0f; this.motion_speed.goal = 0.0f; this.animator = this.behavior.gameObject.GetComponent<Animator>(); this.jump = new ipModule.Jump(); this.jump.gravity *= 3.0f; this.jump.bounciness = new Vector3(1.0f, -0.4f, 1.0f); }
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(); } }
// ================================================================ // // 콜리전의 의미 부여. protected void resolve_collision() { foreach (var result in this.control.collision_results) { if (result.object1 == null) { continue; } //GameObject self = result.object0; GameObject other = result.object1; // 플레이어가 보스의 콜리전에 파뭍혀 움직일 수 없게 되지 않게. // 방의 중심 방향으로 밀어낸다. if (other.tag == "Boss") { if (this.force_push_out(result)) { continue; } } switch (other.tag) { case "Enemy": case "EnemyLair": case "Boss": { do { chrBehaviorEnemy enemy = other.GetComponent <chrBehaviorEnemy>(); if (enemy == null) { break; } if (!this.melee_attack.isInAttackRange(enemy.control)) { //break; } if (this.step.get_current() == STEP.MELEE_ATTACK) { break; } if (!this.melee_attack.isHasInput()) { break; } this.melee_target = enemy; this.step.set_next(STEP.MELEE_ATTACK); } while(false); result.object1 = null; } break; case "Door": { this.cmdNotiryStayDoorBox(other.gameObject.GetComponent <DoorControl>()); } break; case "Item": { do { ItemController item = other.GetComponent <ItemController>(); // 아이템을 주울수있나 조사한다. bool is_pickable = true; switch (item.behavior.item_favor.category) { case Item.CATEGORY.CANDY: { is_pickable = this.item_slot.candy.isVacant(); } break; case Item.CATEGORY.SODA_ICE: case Item.CATEGORY.ETC: { int slot_index = this.item_slot.getEmptyMiscSlot(); // 슬롯이 가득 = 더 가질 수 없을 때. if (slot_index < 0) { is_pickable = false; } } break; case Item.CATEGORY.WEAPON: { // 사용 중인 샷과 같으면 주울 수 없다. SHOT_TYPE shot_type = Item.Weapon.getShotType(item.name); is_pickable = (this.shot_type != shot_type); } break; } if (!is_pickable) { break; } this.control.cmdItemQueryPick(item.name, true, false); } while(false); } break; } } }
public override void execute() { base.execute(); this.resolve_collision(); this.update_item_queries(); // ---------------------------------------------------------------- // // 다음 상태로 전환할지 체크한다. switch (this.step.do_transition()) { // 평상 시. case STEP.MOVE: { if (this.control.vital.getHitPoint() <= 0.0f) { this.step.set_next(STEP.BATAN_Q); } } break; // 근접 공격. case STEP.MELEE_ATTACK: { if (!this.melee_attack.isAttacking()) { this.step.set_next(STEP.MOVE); } } break; // 아이템 사용. case STEP.USE_ITEM: { if (this.step_use_item.transition_check()) { this.ice_timer = ICE_DIGEST_TIME; } } break; // 대미지를 받아 날라가는 중. case STEP.BLOW_OUT: { // 일정 거리를 나아가거나 타임아웃으로 종료. float distance = MathUtility.calcDistanceXZ(this.control.getPosition(), this.step_blow_out.center); if (distance >= this.step_blow_out.radius || this.step.get_time() > BLOW_OUT_TIME) { this.control.cmdSetAcceptDamage(true); this.step.set_next(STEP.MOVE); } } break; // 체력0. case STEP.BATAN_Q: { if (this.control.getMotion() == "") { this.control.cmdSetMotion("m007_out_lp", 1); this.step.set_next_delay(STEP.WAIT_RESTART, 1.0f); } } break; } // ---------------------------------------------------------------- // // 상태 전환 시 초기화. while (this.step.get_next() != STEP.NONE) { switch (this.step.do_initialize()) { // 평상 시. case STEP.MOVE: { this.rigidbody.WakeUp(); this.move_target = this.transform.position; this.heading_target = this.transform.TransformPoint(Vector3.forward); } break; // 근접 공격. case STEP.MELEE_ATTACK: { this.melee_attack.setTarget(this.melee_target); this.melee_attack.attack(true); this.melee_target = null; } break; // 아이템 사용. case STEP.USE_ITEM: { int slot_index = this.step_use_item.slot_index; if (this.ice_timer > 0.0f) { // 아이스를 짧은 간격으로 연속 사용할 때 // 머리가 지끈지끈해서 회복되지 않는다. // 아이템을 삭제한다. ItemWindow.get().clearItem(Item.SLOT_TYPE.MISC, slot_index); this.item_slot.miscs[slot_index].initialize(); this.startJinJin(); this.step.set_next(STEP.MOVE); SoundManager.getInstance().playSE(Sound.ID.DDG_SE_SYS06); } else { this.item_slot.miscs[slot_index].is_using = true; this.control.cmdSetAcceptDamage(false); this.step_use_item.initialize(); } } break; // 대미지를 받아 날라가는 중. case STEP.BLOW_OUT: { this.rigidbody.Sleep(); this.control.cmdSetAcceptDamage(false); } break; // 체력 0 case STEP.BATAN_Q: { this.rigidbody.Sleep(); this.control.cmdSetAcceptDamage(false); this.control.cmdSetMotion("m006_out", 1); } break; // 리스타트 대기. case STEP.WAIT_RESTART: { this.step_batan_q.tears_effect.destroy(); } break; // 외부 제어. case STEP.OUTER_CONTROL: { this.rigidbody.Sleep(); } break; } } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. // 근접 공격. // 일단 false로 해두고 이동 입력이 있을 때만. // true로 한다. this.melee_attack.setHasInput(false); GameInput gi = GameInput.getInstance(); switch (this.step.do_execution(Time.deltaTime)) { // 평상 시. case STEP.MOVE: { this.exec_step_move(); // ショット. if (this.is_shot_enable) { this.bullet_shooter.execute(gi.shot.current); if (gi.shot.current) { CharacterRoot.get().SendAttackData(PartyControl.get().getLocalPlayer().getAcountID(), 0); } } // 체력 회복 직후(레인보우컬러 중)는 무적. if (this.skin_color_control.isNowHealing()) { this.control.cmdSetAcceptDamage(false); } else { this.control.cmdSetAcceptDamage(true); } } break; // 아이템 사용. case STEP.USE_ITEM: { this.step_use_item.execute(); } break; // 대미지를 받아 날라가는 중. case STEP.BLOW_OUT: { this.exec_step_blow_out(); } break; // 체력0. case STEP.BATAN_Q: { if (this.step.is_acrossing_time(4.0f)) { this.step_batan_q.tears_effect = EffectRoot.get().createTearsEffect(this.control.getPosition()); this.step_batan_q.tears_effect.setParent(this.gameObject); this.step_batan_q.tears_effect.setLocalPosition(Vector3.up); } } break; } // ---------------------------------------------------------------- // if (gi.serif_text.trigger_on) { this.control.cmdQueryTalk(gi.serif_text.text, true); } // ---------------------------------------------------------------- // // 10 프레임에 한 번 좌표를 네트워크에 보낸다. { do { if (this.step.get_current() == STEP.OUTER_CONTROL) { break; } m_send_count = (m_send_count + 1) % SplineData.SEND_INTERVAL; if (m_send_count != 0 && m_culling.Count < PLOT_NUM) { break; } // 통신용 좌표 송신. Vector3 target = this.control.getPosition(); CharacterCoord coord = new CharacterCoord(target.x, target.z); Vector3 diff = m_prev - target; if (diff.sqrMagnitude > 0.0001f) { m_culling.Add(coord); AccountData account_data = AccountManager.get().getAccountData(GlobalParam.getInstance().global_account_id); CharacterRoot.get().SendCharacterCoord(account_data.avator_id, m_plotIndex, m_culling); ++m_plotIndex; if (m_culling.Count >= PLOT_NUM) { m_culling.RemoveAt(0); } m_prev = target; } } while(false); } }
// ================================================================ // // 肄쒕━?꾩쓽 ?섎? 遺?? protected void resolve_collision() { foreach (var result in this.control.collision_results) { if (result.object1 == null) { continue; } //GameObject self = result.object0; GameObject other = result.object1; // ?뚮젅?댁뼱媛 蹂댁뒪??肄쒕━?꾩뿉 ?뚮춱? ?吏곸씪 ???녾쾶 ?섏? ?딄쾶. // 諛⑹쓽 以묒떖 諛⑺뼢?쇰줈 諛?대궦?? if (other.tag == "Boss") { if (this.force_push_out(result)) { continue; } } switch (other.tag) { case "Enemy": case "EnemyLair": case "Boss": { do { chrBehaviorEnemy enemy = other.GetComponent <chrBehaviorEnemy>(); if (enemy == null) { break; } if (!this.melee_attack.isInAttackRange(enemy.control)) { //break; } if (this.step.get_current() == STEP.MELEE_ATTACK) { break; } if (!this.melee_attack.isHasInput()) { break; } this.melee_target = enemy; this.step.set_next(STEP.MELEE_ATTACK); } while(false); result.object1 = null; } break; case "Door": { this.cmdNotiryStayDoorBox(other.gameObject.GetComponent <DoorControl>()); } break; case "Item": { do { ItemController item = other.GetComponent <ItemController>(); // ?꾩씠?쒖쓣 二쇱슱?섏엳??議곗궗?쒕떎. bool is_pickable = true; switch (item.behavior.item_favor.category) { case Item.CATEGORY.CANDY: { is_pickable = this.item_slot.candy.isVacant(); } break; case Item.CATEGORY.SODA_ICE: case Item.CATEGORY.ETC: { int slot_index = this.item_slot.getEmptyMiscSlot(); // ?щ’??媛??= ??媛吏????놁쓣 ?? if (slot_index < 0) { is_pickable = false; } } break; case Item.CATEGORY.WEAPON: { // ?ъ슜 以묒씤 ?룰낵 媛숈쑝硫?二쇱슱 ???녿떎. SHOT_TYPE shot_type = Item.Weapon.getShotType(item.name); is_pickable = (this.shot_type != shot_type); } break; } if (!is_pickable) { break; } this.control.cmdItemQueryPick(item.name, true, false); } while(false); } break; } } }
public override void execute() { base.execute(); this.resolve_collision(); this.update_item_queries(); // ---------------------------------------------------------------- // // ?ㅼ쓬 ?곹깭濡??꾪솚?좎? 泥댄겕?쒕떎. switch(this.step.do_transition()) { // ?됱긽 ?? case STEP.MOVE: { if(this.control.vital.getHitPoint() <= 0.0f) { this.step.set_next(STEP.BATAN_Q); } } break; // 洹쇱젒 怨듦꺽. case STEP.MELEE_ATTACK: { if(!this.melee_attack.isAttacking()) { this.step.set_next(STEP.MOVE); } } break; // ?꾩씠???ъ슜. case STEP.USE_ITEM: { if(this.step_use_item.transition_check()) { this.ice_timer = ICE_DIGEST_TIME; } } break; // ?誘몄?瑜?諛쏆븘 ?좊씪媛??以? case STEP.BLOW_OUT: { // ?쇱젙 嫄곕━瑜??섏븘媛嫄곕굹 ??꾩븘?껋쑝濡?醫낅즺. float distance = MathUtility.calcDistanceXZ(this.control.getPosition(), this.step_blow_out.center); if(distance >= this.step_blow_out.radius || this.step.get_time() > BLOW_OUT_TIME) { this.control.cmdSetAcceptDamage(true); this.step.set_next(STEP.MOVE); } } break; // 泥대젰0. case STEP.BATAN_Q: { if(this.control.getMotion() == "") { this.control.cmdSetMotion("m007_out_lp", 1); this.step.set_next_delay(STEP.WAIT_RESTART, 1.0f); } } break; } // ---------------------------------------------------------------- // // ?곹깭 ?꾪솚 ??珥덇린?? while(this.step.get_next() != STEP.NONE) { switch(this.step.do_initialize()) { // ?됱긽 ?? case STEP.MOVE: { this.GetComponent<Rigidbody>().WakeUp(); this.move_target = this.transform.position; this.heading_target = this.transform.TransformPoint(Vector3.forward); } break; // 洹쇱젒 怨듦꺽. case STEP.MELEE_ATTACK: { this.melee_attack.setTarget(this.melee_target); this.melee_attack.attack(true); this.melee_target = null; } break; // ?꾩씠???ъ슜. case STEP.USE_ITEM: { int slot_index = this.step_use_item.slot_index; if(this.ice_timer > 0.0f) { // ?꾩씠?ㅻ? 吏㏃? 媛꾧꺽?쇰줈 ?곗냽 ?ъ슜???? // 癒몃━媛 吏?덉??덊빐???뚮났?섏? ?딅뒗?? // ?꾩씠?쒖쓣 ??젣?쒕떎. ItemWindow.get().clearItem(Item.SLOT_TYPE.MISC, slot_index); this.item_slot.miscs[slot_index].initialize(); this.startJinJin(); this.step.set_next(STEP.MOVE); SoundManager.getInstance().playSE(Sound.ID.DDG_SE_SYS06); } else { this.item_slot.miscs[slot_index].is_using = true; this.control.cmdSetAcceptDamage(false); this.step_use_item.initialize(); } } break; // ?誘몄?瑜?諛쏆븘 ?좊씪媛??以? case STEP.BLOW_OUT: { this.GetComponent<Rigidbody>().Sleep(); this.control.cmdSetAcceptDamage(false); } break; // 泥대젰 0 case STEP.BATAN_Q: { this.GetComponent<Rigidbody>().Sleep(); this.control.cmdSetAcceptDamage(false); this.control.cmdSetMotion("m006_out", 1); } break; // 由ъ뒪????湲? case STEP.WAIT_RESTART: { this.step_batan_q.tears_effect.destroy(); } break; // ?몃? ?쒖뼱. case STEP.OUTER_CONTROL: { this.GetComponent<Rigidbody>().Sleep(); } break; } } // ---------------------------------------------------------------- // // 媛??곹깭?먯꽌???ㅽ뻾 泥섎━. // 洹쇱젒 怨듦꺽. // ?쇰떒 false濡??대몢怨??대룞 ?낅젰???덉쓣 ?뚮쭔. // true濡??쒕떎. this.melee_attack.setHasInput(false); GameInput gi = GameInput.getInstance(); switch(this.step.do_execution(Time.deltaTime)) { // ?됱긽 ?? case STEP.MOVE: { this.exec_step_move(); // ?룔깾?껁깉. if(this.is_shot_enable) { this.bullet_shooter.execute(gi.shot.current); if(gi.shot.current) { CharacterRoot.get().SendAttackData(PartyControl.get().getLocalPlayer().getAcountID(), 0); } } // 泥대젰 ?뚮났 吏곹썑(?덉씤蹂댁슦而щ윭 以???臾댁쟻. if(this.skin_color_control.isNowHealing()) { this.control.cmdSetAcceptDamage(false); } else { this.control.cmdSetAcceptDamage(true); } } break; // ?꾩씠???ъ슜. case STEP.USE_ITEM: { this.step_use_item.execute(); } break; // ?誘몄?瑜?諛쏆븘 ?좊씪媛??以? case STEP.BLOW_OUT: { this.exec_step_blow_out(); } break; // 泥대젰0. case STEP.BATAN_Q: { if(this.step.is_acrossing_time(4.0f)) { this.step_batan_q.tears_effect = EffectRoot.get().createTearsEffect(this.control.getPosition()); this.step_batan_q.tears_effect.setParent(this.gameObject); this.step_batan_q.tears_effect.setLocalPosition(Vector3.up); } } break; } // ---------------------------------------------------------------- // if(gi.serif_text.trigger_on) { this.control.cmdQueryTalk(gi.serif_text.text, true); } // ---------------------------------------------------------------- // // 10 ?꾨젅?꾩뿉 ??踰?醫뚰몴瑜??ㅽ듃?뚰겕??蹂대궦?? { do { if(this.step.get_current() == STEP.OUTER_CONTROL) { break; } m_send_count = (m_send_count + 1)%SplineData.SEND_INTERVAL; if(m_send_count != 0 && m_culling.Count < PLOT_NUM) { break; } // ?듭떊??醫뚰몴 ?≪떊. Vector3 target = this.control.getPosition(); CharacterCoord coord = new CharacterCoord(target.x, target.z); Vector3 diff = m_prev - target; if (diff.sqrMagnitude > 0.0001f) { m_culling.Add(coord); AccountData account_data = AccountManager.get().getAccountData(GlobalParam.getInstance().global_account_id); CharacterRoot.get().SendCharacterCoord(account_data.avator_id, m_plotIndex, m_culling); ++m_plotIndex; if (m_culling.Count >= PLOT_NUM) { m_culling.RemoveAt(0); } m_prev = target; } } while(false); } }
// ================================================================ // // 생성합니다. public virtual void create(chrBehaviorEnemy behavior, ActionBase.DescBase desc_base = null) { this.behavior = behavior; this.control = behavior.control; }
public override void execute() { base.execute(); this.resolve_collision(); this.update_item_queries(); // ---------------------------------------------------------------- // // 다음 상태로 전환할지 체크한다. switch(this.step.do_transition()) { // 평상 시. case STEP.MOVE: { if(this.control.vital.getHitPoint() <= 0.0f) { this.step.set_next(STEP.BATAN_Q); } } break; // 근접 공격. case STEP.MELEE_ATTACK: { if(!this.melee_attack.isAttacking()) { this.step.set_next(STEP.MOVE); } } break; // 아이템 사용. case STEP.USE_ITEM: { if(this.step_use_item.transition_check()) { this.ice_timer = ICE_DIGEST_TIME; } } break; // 대미지를 받아 날라가는 중. case STEP.BLOW_OUT: { // 일정 거리를 나아가거나 타임아웃으로 종료. float distance = MathUtility.calcDistanceXZ(this.control.getPosition(), this.step_blow_out.center); if(distance >= this.step_blow_out.radius || this.step.get_time() > BLOW_OUT_TIME) { this.control.cmdSetAcceptDamage(true); this.step.set_next(STEP.MOVE); } } break; // 체력0. case STEP.BATAN_Q: { if(this.control.getMotion() == "") { this.control.cmdSetMotion("m007_out_lp", 1); this.step.set_next_delay(STEP.WAIT_RESTART, 1.0f); } } break; } // ---------------------------------------------------------------- // // 상태 전환 시 초기화. while(this.step.get_next() != STEP.NONE) { switch(this.step.do_initialize()) { // 평상 시. case STEP.MOVE: { this.rigidbody.WakeUp(); this.move_target = this.transform.position; this.heading_target = this.transform.TransformPoint(Vector3.forward); } break; // 근접 공격. case STEP.MELEE_ATTACK: { this.melee_attack.setTarget(this.melee_target); this.melee_attack.attack(true); this.melee_target = null; } break; // 아이템 사용. case STEP.USE_ITEM: { int slot_index = this.step_use_item.slot_index; if(this.ice_timer > 0.0f) { // 아이스를 짧은 간격으로 연속 사용할 때 // 머리가 지끈지끈해서 회복되지 않는다. // 아이템을 삭제한다. ItemWindow.get().clearItem(Item.SLOT_TYPE.MISC, slot_index); this.item_slot.miscs[slot_index].initialize(); this.startJinJin(); this.step.set_next(STEP.MOVE); SoundManager.getInstance().playSE(Sound.ID.DDG_SE_SYS06); } else { this.item_slot.miscs[slot_index].is_using = true; this.control.cmdSetAcceptDamage(false); this.step_use_item.initialize(); } } break; // 대미지를 받아 날라가는 중. case STEP.BLOW_OUT: { this.rigidbody.Sleep(); this.control.cmdSetAcceptDamage(false); } break; // 체력 0 case STEP.BATAN_Q: { this.rigidbody.Sleep(); this.control.cmdSetAcceptDamage(false); this.control.cmdSetMotion("m006_out", 1); } break; // 리스타트 대기. case STEP.WAIT_RESTART: { this.step_batan_q.tears_effect.destroy(); } break; // 외부 제어. case STEP.OUTER_CONTROL: { this.rigidbody.Sleep(); } break; } } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. // 근접 공격. // 일단 false로 해두고 이동 입력이 있을 때만. // true로 한다. this.melee_attack.setHasInput(false); GameInput gi = GameInput.getInstance(); switch(this.step.do_execution(Time.deltaTime)) { // 평상 시. case STEP.MOVE: { this.exec_step_move(); // ショット. if(this.is_shot_enable) { this.bullet_shooter.execute(gi.shot.current); if(gi.shot.current) { CharacterRoot.get().SendAttackData(PartyControl.get().getLocalPlayer().getAcountID(), 0); } } // 체력 회복 직후(레인보우컬러 중)는 무적. if(this.skin_color_control.isNowHealing()) { this.control.cmdSetAcceptDamage(false); } else { this.control.cmdSetAcceptDamage(true); } } break; // 아이템 사용. case STEP.USE_ITEM: { this.step_use_item.execute(); } break; // 대미지를 받아 날라가는 중. case STEP.BLOW_OUT: { this.exec_step_blow_out(); } break; // 체력0. case STEP.BATAN_Q: { if(this.step.is_acrossing_time(4.0f)) { this.step_batan_q.tears_effect = EffectRoot.get().createTearsEffect(this.control.getPosition()); this.step_batan_q.tears_effect.setParent(this.gameObject); this.step_batan_q.tears_effect.setLocalPosition(Vector3.up); } } break; } // ---------------------------------------------------------------- // if(gi.serif_text.trigger_on) { this.control.cmdQueryTalk(gi.serif_text.text, true); } // ---------------------------------------------------------------- // // 10 프레임에 한 번 좌표를 네트워크에 보낸다. { do { if(this.step.get_current() == STEP.OUTER_CONTROL) { break; } m_send_count = (m_send_count + 1)%SplineData.SEND_INTERVAL; if(m_send_count != 0 && m_culling.Count < PLOT_NUM) { break; } // 통신용 좌표 송신. Vector3 target = this.control.getPosition(); CharacterCoord coord = new CharacterCoord(target.x, target.z); Vector3 diff = m_prev - target; if (diff.sqrMagnitude > 0.0001f) { m_culling.Add(coord); AccountData account_data = AccountManager.get().getAccountData(GlobalParam.getInstance().global_account_id); CharacterRoot.get().SendCharacterCoord(account_data.avator_id, m_plotIndex, m_culling); ++m_plotIndex; if (m_culling.Count >= PLOT_NUM) { m_culling.RemoveAt(0); } m_prev = target; } } while(false); } }
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() { base.execute(); this.resolve_collision(); this.update_item_queries(); // ---------------------------------------------------------------- // // ?ㅼ쓬 ?곹깭濡??꾪솚?좎? 泥댄겕?쒕떎. switch (this.step.do_transition()) { // ?됱긽 ?? case STEP.MOVE: { if (this.control.vital.getHitPoint() <= 0.0f) { this.step.set_next(STEP.BATAN_Q); } } break; // 洹쇱젒 怨듦꺽. case STEP.MELEE_ATTACK: { if (!this.melee_attack.isAttacking()) { this.step.set_next(STEP.MOVE); } } break; // ?꾩씠???ъ슜. case STEP.USE_ITEM: { if (this.step_use_item.transition_check()) { this.ice_timer = ICE_DIGEST_TIME; } } break; // ?誘몄?瑜?諛쏆븘 ?좊씪媛??以? case STEP.BLOW_OUT: { // ?쇱젙 嫄곕━瑜??섏븘媛嫄곕굹 ??꾩븘?껋쑝濡?醫낅즺. float distance = MathUtility.calcDistanceXZ(this.control.getPosition(), this.step_blow_out.center); if (distance >= this.step_blow_out.radius || this.step.get_time() > BLOW_OUT_TIME) { this.control.cmdSetAcceptDamage(true); this.step.set_next(STEP.MOVE); } } break; // 泥대젰0. case STEP.BATAN_Q: { if (this.control.getMotion() == "") { this.control.cmdSetMotion("m007_out_lp", 1); this.step.set_next_delay(STEP.WAIT_RESTART, 1.0f); } } break; } // ---------------------------------------------------------------- // // ?곹깭 ?꾪솚 ??珥덇린?? while (this.step.get_next() != STEP.NONE) { switch (this.step.do_initialize()) { // ?됱긽 ?? case STEP.MOVE: { this.GetComponent <Rigidbody>().WakeUp(); this.move_target = this.transform.position; this.heading_target = this.transform.TransformPoint(Vector3.forward); } break; // 洹쇱젒 怨듦꺽. case STEP.MELEE_ATTACK: { this.melee_attack.setTarget(this.melee_target); this.melee_attack.attack(true); this.melee_target = null; } break; // ?꾩씠???ъ슜. case STEP.USE_ITEM: { int slot_index = this.step_use_item.slot_index; if (this.ice_timer > 0.0f) { // ?꾩씠?ㅻ? 吏㏃? 媛꾧꺽?쇰줈 ?곗냽 ?ъ슜???? // 癒몃━媛 吏?덉??덊빐???뚮났?섏? ?딅뒗?? // ?꾩씠?쒖쓣 ??젣?쒕떎. ItemWindow.get().clearItem(Item.SLOT_TYPE.MISC, slot_index); this.item_slot.miscs[slot_index].initialize(); this.startJinJin(); this.step.set_next(STEP.MOVE); SoundManager.getInstance().playSE(Sound.ID.DDG_SE_SYS06); } else { this.item_slot.miscs[slot_index].is_using = true; this.control.cmdSetAcceptDamage(false); this.step_use_item.initialize(); } } break; // ?誘몄?瑜?諛쏆븘 ?좊씪媛??以? case STEP.BLOW_OUT: { this.GetComponent <Rigidbody>().Sleep(); this.control.cmdSetAcceptDamage(false); } break; // 泥대젰 0 case STEP.BATAN_Q: { this.GetComponent <Rigidbody>().Sleep(); this.control.cmdSetAcceptDamage(false); this.control.cmdSetMotion("m006_out", 1); } break; // 由ъ뒪????湲? case STEP.WAIT_RESTART: { this.step_batan_q.tears_effect.destroy(); } break; // ?몃? ?쒖뼱. case STEP.OUTER_CONTROL: { this.GetComponent <Rigidbody>().Sleep(); } break; } } // ---------------------------------------------------------------- // // 媛??곹깭?먯꽌???ㅽ뻾 泥섎━. // 洹쇱젒 怨듦꺽. // ?쇰떒 false濡??대몢怨??대룞 ?낅젰???덉쓣 ?뚮쭔. // true濡??쒕떎. this.melee_attack.setHasInput(false); GameInput gi = GameInput.getInstance(); switch (this.step.do_execution(Time.deltaTime)) { // ?됱긽 ?? case STEP.MOVE: { this.exec_step_move(); // ?룔깾?껁깉. if (this.is_shot_enable) { this.bullet_shooter.execute(gi.shot.current); if (gi.shot.current) { CharacterRoot.get().SendAttackData(PartyControl.get().getLocalPlayer().getAcountID(), 0); } } // 泥대젰 ?뚮났 吏곹썑(?덉씤蹂댁슦而щ윭 以???臾댁쟻. if (this.skin_color_control.isNowHealing()) { this.control.cmdSetAcceptDamage(false); } else { this.control.cmdSetAcceptDamage(true); } } break; // ?꾩씠???ъ슜. case STEP.USE_ITEM: { this.step_use_item.execute(); } break; // ?誘몄?瑜?諛쏆븘 ?좊씪媛??以? case STEP.BLOW_OUT: { this.exec_step_blow_out(); } break; // 泥대젰0. case STEP.BATAN_Q: { if (this.step.is_acrossing_time(4.0f)) { this.step_batan_q.tears_effect = EffectRoot.get().createTearsEffect(this.control.getPosition()); this.step_batan_q.tears_effect.setParent(this.gameObject); this.step_batan_q.tears_effect.setLocalPosition(Vector3.up); } } break; } // ---------------------------------------------------------------- // if (gi.serif_text.trigger_on) { this.control.cmdQueryTalk(gi.serif_text.text, true); } // ---------------------------------------------------------------- // // 10 ?꾨젅?꾩뿉 ??踰?醫뚰몴瑜??ㅽ듃?뚰겕??蹂대궦?? { do { if (this.step.get_current() == STEP.OUTER_CONTROL) { break; } m_send_count = (m_send_count + 1) % SplineData.SEND_INTERVAL; if (m_send_count != 0 && m_culling.Count < PLOT_NUM) { break; } // ?듭떊??醫뚰몴 ?≪떊. Vector3 target = this.control.getPosition(); CharacterCoord coord = new CharacterCoord(target.x, target.z); Vector3 diff = m_prev - target; if (diff.sqrMagnitude > 0.0001f) { m_culling.Add(coord); AccountData account_data = AccountManager.get().getAccountData(GlobalParam.getInstance().global_account_id); CharacterRoot.get().SendCharacterCoord(account_data.avator_id, m_plotIndex, m_culling); ++m_plotIndex; if (m_culling.Count >= PLOT_NUM) { m_culling.RemoveAt(0); } m_prev = target; } } while(false); } }
// 매 프레임 실행. public override void execute() { this.position_xz = this.control.getPosition(); // ---------------------------------------------------------------- // // 다음 상태로 이행할지 체크합니다. switch (this.step.do_transition()) { // 상자(제네레이터)에서 튀어나오는 중. case STEP.SPAWN: { if (this.jump.isDone()) { this.step.set_next(STEP.UNIQUE); } } break; // 바이바~이~. case STEP.VANISH: { if (this.behavior.control.damage_effect.isVacant()) { // 자기 자신의 인스턴스를 삭제합니다. this.behavior.deleteSelf(); } } break; } // ---------------------------------------------------------------- // // 상태가 전환했을 때의 초기화. while (this.step.get_next() != STEP.NONE) { switch (this.step.do_initialize()) { case STEP.UNIQUE: { this.unique_action.parent = this; this.unique_action.start(); } break; // 상자(제네레이터)에서 튀어나오는 중. case STEP.SPAWN: { this.control.cmdSetDirection(this.move_dir); } break; // 바이바~이~. case STEP.VANISH: { this.animator.speed = 0.0f; this.control.cmdBeginVanish(); } break; // 그 자리에서 멈춥니다. case STEP.STILL: { this.setMoveMotionSpeed(0.0f); } break; } } // ---------------------------------------------------------------- // // 각 상태에서의 실행 처리. switch (this.step.do_execution(Time.deltaTime)) { case STEP.UNIQUE: { this.unique_action.execute(); } break; // 상자(제네레이터)에서 튀어나오는 중(착지까지). case STEP.SPAWN: { this.position_xz += this.jump.xz_velocity() * Time.deltaTime; } break; } this.unique_action.stealth(); // ---------------------------------------------------------------- // this.update_motion_speed(); this.jump.execute(Time.deltaTime); this.position_xz.y = this.jump.position.y; // 방 외벽을 넘어가지 않도록. do { chrBehaviorEnemy behavior = this.control.behavior as chrBehaviorEnemy; if (behavior == null) { break; } Rect room_rect = MapCreator.get().getRoomRect(behavior.room.getIndex()); this.wall_coli.is_valid = false; if (this.position_xz.x < room_rect.min.x) { this.position_xz.x = room_rect.min.x; this.wall_coli.is_valid = true; this.wall_coli.normal = Vector3.right; } if (this.position_xz.x > room_rect.max.x) { this.position_xz.x = room_rect.max.x; this.wall_coli.is_valid = true; this.wall_coli.normal = Vector3.left; } if (this.position_xz.z < room_rect.min.y) { this.position_xz.z = room_rect.min.y; this.wall_coli.is_valid = true; this.wall_coli.normal = Vector3.forward; } if (this.position_xz.z > room_rect.max.y) { this.position_xz.z = room_rect.max.y; this.wall_coli.is_valid = true; this.wall_coli.normal = Vector3.back; } } while(false); this.control.cmdSetPosition(this.position_xz); // 벽에 부딪히면 벽을 따라 이동 방향을 바꿉니다. do { if (!this.wall_coli.is_valid) { break; } Vector3 v = Quaternion.AngleAxis(this.move_dir, Vector3.up) * Vector3.forward; float dp = Vector3.Dot(v, this.wall_coli.normal); if (dp > 0.0f) { break; } v = v - 2.0f * this.wall_coli.normal * dp; this.move_dir = Mathf.Atan2(v.x, v.z) * Mathf.Rad2Deg; } while(false); // 턴(방향 보간). if (this.turn_rate > 0.0f) { this.control.cmdSmoothDirection(this.move_dir, this.turn_rate); this.turn_rate = 0.0f; } else { this.control.cmdSmoothDirection(this.move_dir); } }
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(); }
// ================================================================ // // 肄쒕━?꾩쓽 ?섎? 遺?? protected void resolve_collision() { foreach(var result in this.control.collision_results) { if(result.object1 == null) { continue; } //GameObject self = result.object0; GameObject other = result.object1; // ?뚮젅?댁뼱媛 蹂댁뒪??肄쒕━?꾩뿉 ?뚮춱? ?吏곸씪 ???녾쾶 ?섏? ?딄쾶. // 諛⑹쓽 以묒떖 諛⑺뼢?쇰줈 諛?대궦?? if(other.tag == "Boss") { if(this.force_push_out(result)) { continue; } } switch(other.tag) { case "Enemy": case "EnemyLair": case "Boss": { do { chrBehaviorEnemy enemy = other.GetComponent<chrBehaviorEnemy>(); if(enemy == null) { break; } if(!this.melee_attack.isInAttackRange(enemy.control)) { //break; } if(this.step.get_current() == STEP.MELEE_ATTACK) { break; } if(!this.melee_attack.isHasInput()) { break; } this.melee_target = enemy; this.step.set_next(STEP.MELEE_ATTACK); } while(false); result.object1 = null; } break; case "Door": { this.cmdNotiryStayDoorBox(other.gameObject.GetComponent<DoorControl>()); } break; case "Item": { do { ItemController item = other.GetComponent<ItemController>(); // ?꾩씠?쒖쓣 二쇱슱?섏엳??議곗궗?쒕떎. bool is_pickable = true; switch(item.behavior.item_favor.category) { case Item.CATEGORY.CANDY: { is_pickable = this.item_slot.candy.isVacant(); } break; case Item.CATEGORY.SODA_ICE: case Item.CATEGORY.ETC: { int slot_index = this.item_slot.getEmptyMiscSlot(); // ?щ’??媛??= ??媛吏????놁쓣 ?? if(slot_index < 0) { is_pickable = false; } } break; case Item.CATEGORY.WEAPON: { // ?ъ슜 以묒씤 ?룰낵 媛숈쑝硫?二쇱슱 ???녿떎. SHOT_TYPE shot_type = Item.Weapon.getShotType(item.name); is_pickable = (this.shot_type != shot_type); } break; } if(!is_pickable) { break; } this.control.cmdItemQueryPick(item.name, true, false); } while(false); } break; } } }
// ================================================================ // public override void create(chrBehaviorEnemy behavior, ActionBase.DescBase desc_base = null) { base.create(behavior, desc_base); Desc desc = desc_base as Desc; if(desc == null) { desc = new Desc(this.control.getPosition()); } this.positions[0] = desc.position0; this.positions[1] = desc.position1; this.melee_attack = new MeleeAttackAction(); this.melee_attack.create(this.behavior); }