227 lines
9.0 KiB
TypeScript
227 lines
9.0 KiB
TypeScript
/*
|
|
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
|
|
|
|
https://www.cocos.com/
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights to
|
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
*/
|
|
|
|
import { _decorator, Node, game, math } from 'cc';
|
|
import { Msg } from "../../core/msg/msg";
|
|
import { Res } from '../../core/res/res';
|
|
import { ResCache } from '../../core/res/res-cache';
|
|
import { UtilNode } from '../../core/util/util';
|
|
import { Actor } from "./actor";
|
|
import { BagItem } from './actor-bag';
|
|
import { fun } from '../../core/util/fun';
|
|
import { ActorEquipBase } from './actor-equip-base';
|
|
|
|
|
|
export class ActorEquipment {
|
|
|
|
// The character object to which the current equipment belongs.
|
|
_actor:Actor;
|
|
|
|
// A pool of cached equipment objects.
|
|
//The purpose is to avoid the creation and destruction of objects at runtime.
|
|
equipPool:{ [key:string]:Node } = {};
|
|
|
|
// Dictionary of weapon skeleton nodes for mounted equipment.
|
|
equipBoneNode: { [key:string]:Node } = {};
|
|
|
|
// Current equipment node.
|
|
currentEquipNode:Node | undefined;
|
|
|
|
// bag information of current equipment.
|
|
currentEquipItem:BagItem | undefined;
|
|
|
|
// The component object of the current weapon.
|
|
currentEquip:ActorEquipBase | undefined;
|
|
|
|
// The stability value of the equipment.
|
|
// The purpose is to describe the stability value of the shot.
|
|
// This value affects the size of the aiming area of the shot.
|
|
stableValue = 1;
|
|
|
|
constructor(actor:Actor) {
|
|
|
|
// Initialize the Actor object corresponding to the equipment manager passed in.
|
|
this._actor = actor;
|
|
|
|
// Get all node maps with the name 'weapon_root'.
|
|
this.equipBoneNode = UtilNode.getChildrenByNameBlur(this._actor.node, 'weapon_root');
|
|
|
|
// Initialize the cache pool for the equipment list.
|
|
const equipmentList = this._actor._data.cache_equipment_list;
|
|
|
|
// Get the length of the equipment list.
|
|
const length = equipmentList.length;
|
|
for(let i = 0; i < length; i++) {
|
|
|
|
// Get the equipment name from the current index.
|
|
const weaponName = equipmentList[i];
|
|
|
|
// Get the prefab of the equipment from the resource buffer pool.
|
|
const prefab = ResCache.Instance.getPrefab(weaponName + '_tps');
|
|
|
|
// Get the bone node of the equipment.
|
|
const bindNode = this.equipBoneNode[this._actor._data.weapon_bone];
|
|
|
|
// Instantiate the game object and set the parent node to the bone node.
|
|
const nodePrefab = Res.inst(prefab, bindNode);
|
|
|
|
// Set the object pool key to map to this instantiated weapon object.
|
|
this.equipPool[weaponName] = nodePrefab;
|
|
|
|
// Set the activity of this cache object to false.
|
|
nodePrefab.active = false;
|
|
}
|
|
|
|
// Equip the default weapon.
|
|
this.equip(actor._data.default_equip_index);
|
|
}
|
|
|
|
public equip(replaceEquipmentIndex:number):boolean {
|
|
|
|
// Get the current bag equipment index.
|
|
const currentEquipmentIndex = this._actor._data.current_equipment_index;
|
|
|
|
// If the current bag index is the same as the updated bag index,
|
|
// true is no need to switch weapons, false is need to switch weapons.
|
|
if (currentEquipmentIndex !== replaceEquipmentIndex) {
|
|
|
|
// Get bag equipment name list from player data.
|
|
const equipment_name_list = this._actor._data.equipment_name_list;
|
|
|
|
// Get the name of the equipment name to be switched from the equipment list.
|
|
const changeEquipmentName = equipment_name_list[replaceEquipmentIndex];
|
|
|
|
// Return false if the equipment does not exist or is not empty to cancel switching equipment.
|
|
if(!changeEquipmentName || changeEquipmentName.length <= 0) return false;
|
|
|
|
// Uninstall current equipment.
|
|
this.unEquip();
|
|
|
|
// Replace new equipment data and models.
|
|
// Here you need to do a time delay with the animation.
|
|
const self = this;
|
|
fun.delay(()=>{
|
|
const items = self._actor._data.items;
|
|
self.currentEquipNode = self.equipPool[changeEquipmentName];
|
|
self.currentEquipItem = items[changeEquipmentName];
|
|
self.currentEquipNode!.active = true;
|
|
self.currentEquipNode!.emit('init',this.currentEquipItem);
|
|
self.currentEquipNode!.emit('do', 'take_out');
|
|
self._actor._data.current_equipment_index = replaceEquipmentIndex;
|
|
self.currentEquip = self.currentEquipNode?.getComponent(ActorEquipBase)!;
|
|
if(this._actor.isPlayer) {
|
|
//const mainCamera = CameraSetting.main?.camera;
|
|
//if(mainCamera) mainCamera.fov = this.currentEquipItem!.fov;
|
|
Msg.emit('msg_change_equip');
|
|
Msg.emit('msg_update_equip_info');
|
|
}
|
|
}, 0.3)
|
|
|
|
return true;
|
|
|
|
}else{
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Uninstall current equipment.
|
|
*/
|
|
public unEquip() {
|
|
|
|
//Get the index of the current equipment.s
|
|
const currentEquipmentIndex = this._actor._data.current_equipment_index;
|
|
|
|
// Compare whether the current equipment index value is -1.
|
|
// An index of -1 means no current equipment, skip setting.
|
|
if (currentEquipmentIndex !== -1) {
|
|
|
|
// Get a list of equipment names.
|
|
const equipment_name_list = this._actor._data.equipment_name_list;
|
|
|
|
// Get the current equipment name.
|
|
const currentEquipmentName = equipment_name_list[currentEquipmentIndex];
|
|
|
|
// Whether the current equipment name exists.
|
|
// false means it does not exist, the return function does not uninstall the equipment
|
|
if(!currentEquipmentName) {
|
|
console.warn(`The equipment index that does not exist, the index id is ${currentEquipmentIndex}, the object is ${this._actor?.node.name}`)
|
|
return;
|
|
}
|
|
|
|
// Get the current equipment object node from the equipment object pool.
|
|
const currentEquipmentNode = this.equipPool[currentEquipmentName];
|
|
|
|
//Whether the object pool contains equipment objects.
|
|
if (currentEquipmentNode) {
|
|
// Notify the equipment node to perform recovery behavior.
|
|
currentEquipmentNode.emit('do', 'take_back');
|
|
}else{
|
|
console.warn(``);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Execution equipment action.
|
|
* @param action Name of the execution action.
|
|
*/
|
|
public do(action:string) {
|
|
// Execute the current equipment action.
|
|
this.currentEquipNode?.emit('do', action);
|
|
}
|
|
|
|
/**
|
|
* Update to set the range of Aim.
|
|
* @param normalizeCharacterMoveSpeed Normalized character movement speed.
|
|
* @param toMax The aim range is set to the maximum value: true is set, false is not set.
|
|
*/
|
|
public updateAim(normalizeCharacterMoveSpeed:number, toMax = false) {
|
|
|
|
if (this.currentEquipItem === undefined) {
|
|
if (this.stableValue !== 0){
|
|
this.stableValue = 0;
|
|
if(this._actor.isPlayer) Msg.emit('msg_update_aim', this.stableValue);
|
|
}
|
|
}else{
|
|
const equipData = this.currentEquipItem.data;
|
|
const equipStable = equipData.stable_max_value;
|
|
let currentStable = 0;
|
|
if(toMax) {
|
|
this.stableValue = equipData.stable_max_value;
|
|
currentStable = equipData.stable_max_value;
|
|
}else{
|
|
if (equipStable !== 0) {
|
|
currentStable = Math.abs(normalizeCharacterMoveSpeed) <= 0.001 ? equipData.stable_min_value : equipData.stable_max_value * normalizeCharacterMoveSpeed;
|
|
currentStable = Math.max(equipData.stable_min_value, currentStable);
|
|
}
|
|
this.stableValue = math.lerp(this.stableValue, currentStable, game.deltaTime * equipData.stable_smooth);
|
|
}
|
|
|
|
if(this._actor.isPlayer) Msg.emit('msg_update_aim', this.stableValue);
|
|
}
|
|
}
|
|
|
|
} |