Merge branch 'develop' into feature/task-emote
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &4998203355105501952
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1628544740079825057}
|
||||
- component: {fileID: 2396821685412871444}
|
||||
- component: {fileID: 7258523983903280597}
|
||||
- component: {fileID: 2200587088708437140}
|
||||
- component: {fileID: 8677225758390490087}
|
||||
m_Layer: 0
|
||||
m_Name: FreeLook Camera
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1628544740079825057
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4998203355105501952}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0.23378472, y: -1.6779091e-15, z: 8.341431e-16, w: 0.9722884}
|
||||
m_LocalPosition: {x: -736.68787, y: 50.89, z: -269.46097}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &2396821685412871444
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4998203355105501952}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f9dfa5b682dcd46bda6128250e975f58, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
Priority:
|
||||
Enabled: 0
|
||||
m_Value: 0
|
||||
OutputChannel: 1
|
||||
StandbyUpdate: 2
|
||||
m_StreamingVersion: 20241001
|
||||
m_LegacyPriority: 0
|
||||
Target:
|
||||
TrackingTarget: {fileID: 0}
|
||||
LookAtTarget: {fileID: 0}
|
||||
CustomLookAtTarget: 0
|
||||
Lens:
|
||||
FieldOfView: 60.000004
|
||||
OrthographicSize: 5
|
||||
NearClipPlane: 0.3
|
||||
FarClipPlane: 200
|
||||
Dutch: 0
|
||||
ModeOverride: 0
|
||||
PhysicalProperties:
|
||||
GateFit: 2
|
||||
SensorSize: {x: 21.946, y: 16.002}
|
||||
LensShift: {x: 0, y: 0}
|
||||
FocusDistance: 10
|
||||
Iso: 200
|
||||
ShutterSpeed: 0.005
|
||||
Aperture: 16
|
||||
BladeCount: 5
|
||||
Curvature: {x: 2, y: 11}
|
||||
BarrelClipping: 0.25
|
||||
Anamorphism: 0
|
||||
BlendHint: 0
|
||||
--- !u!114 &7258523983903280597
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4998203355105501952}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 3b5d7c088409d9a40b7b09aa707777f8, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
TargetOffset: {x: 0, y: 4, z: 0}
|
||||
TrackerSettings:
|
||||
BindingMode: 4
|
||||
PositionDamping: {x: 1, y: 1, z: 1}
|
||||
AngularDampingMode: 0
|
||||
RotationDamping: {x: 1, y: 1, z: 1}
|
||||
QuaternionDamping: 1.52
|
||||
OrbitStyle: 1
|
||||
Radius: 1
|
||||
Orbits:
|
||||
Top:
|
||||
Radius: 0.03
|
||||
Height: 7.26
|
||||
Center:
|
||||
Radius: 8.33
|
||||
Height: 5.99
|
||||
Bottom:
|
||||
Radius: 4.29
|
||||
Height: -4.04
|
||||
SplineCurvature: 0
|
||||
RecenteringTarget: 2
|
||||
HorizontalAxis:
|
||||
Value: 208
|
||||
Center: 0
|
||||
Range: {x: -360, y: 360}
|
||||
Wrap: 0
|
||||
Recentering:
|
||||
Enabled: 0
|
||||
Wait: 1
|
||||
Time: 2
|
||||
Restrictions: 0
|
||||
VerticalAxis:
|
||||
Value: -268
|
||||
Center: 20
|
||||
Range: {x: -360, y: 360}
|
||||
Wrap: 1
|
||||
Recentering:
|
||||
Enabled: 0
|
||||
Wait: 1
|
||||
Time: 2
|
||||
Restrictions: 0
|
||||
RadialAxis:
|
||||
Value: 1
|
||||
Center: 1
|
||||
Range: {x: 1, y: 1}
|
||||
Wrap: 0
|
||||
Recentering:
|
||||
Enabled: 0
|
||||
Wait: 1
|
||||
Time: 2
|
||||
Restrictions: 0
|
||||
--- !u!114 &2200587088708437140
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4998203355105501952}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f38bda98361e1de48a4ca2bd86ea3c17, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
Composition:
|
||||
ScreenPosition: {x: 0, y: 0}
|
||||
DeadZone:
|
||||
Enabled: 0
|
||||
Size: {x: 0.2, y: 0.2}
|
||||
HardLimits:
|
||||
Enabled: 0
|
||||
Size: {x: 0.8, y: 0.8}
|
||||
Offset: {x: 0, y: 0}
|
||||
CenterOnActivate: 1
|
||||
TargetOffset: {x: 0, y: 1.5, z: 0}
|
||||
Damping: {x: 0.5, y: 0.5}
|
||||
Lookahead:
|
||||
Enabled: 0
|
||||
Time: 0
|
||||
Smoothing: 0
|
||||
IgnoreY: 0
|
||||
--- !u!114 &8677225758390490087
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4998203355105501952}
|
||||
m_Enabled: 0
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 89875cdc57c54474a8a74efd9b2a3b5d, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
ScanRecursively: 1
|
||||
SuppressInputWhileBlending: 1
|
||||
IgnoreTimeScale: 0
|
||||
m_ControllerManager:
|
||||
Controllers:
|
||||
- Name: Look Orbit X
|
||||
Owner: {fileID: 7258523983903280597}
|
||||
Enabled: 1
|
||||
Input:
|
||||
InputAction: {fileID: -5630151704836100654, guid: 1d6e640e716dc4ff6989b73d02023f2b, type: 3}
|
||||
Gain: 1
|
||||
LegacyInput:
|
||||
LegacyGain: 1
|
||||
CancelDeltaTime: 0
|
||||
InputValue: 0
|
||||
Driver:
|
||||
AccelTime: 0.2
|
||||
DecelTime: 0.2
|
||||
- Name: Look Orbit Y
|
||||
Owner: {fileID: 7258523983903280597}
|
||||
Enabled: 1
|
||||
Input:
|
||||
InputAction: {fileID: -5630151704836100654, guid: 1d6e640e716dc4ff6989b73d02023f2b, type: 3}
|
||||
Gain: -1
|
||||
LegacyInput:
|
||||
LegacyGain: 1
|
||||
CancelDeltaTime: 0
|
||||
InputValue: 0
|
||||
Driver:
|
||||
AccelTime: 0.2
|
||||
DecelTime: 0.2
|
||||
- Name: Orbit Scale
|
||||
Owner: {fileID: 7258523983903280597}
|
||||
Enabled: 1
|
||||
Input:
|
||||
InputAction: {fileID: -423771258819551211, guid: 1d6e640e716dc4ff6989b73d02023f2b, type: 3}
|
||||
Gain: -1
|
||||
LegacyInput:
|
||||
LegacyGain: 1
|
||||
CancelDeltaTime: 0
|
||||
InputValue: 0
|
||||
Driver:
|
||||
AccelTime: 0
|
||||
DecelTime: 0
|
||||
PlayerIndex: -1
|
||||
AutoEnableInputs: 0
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc901dd976e0838499b18a0b802b81d7
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,5 +1,98 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &1907375868528687128
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3488899534283412697}
|
||||
- component: {fileID: 7907247812297230186}
|
||||
- component: {fileID: 4758101108332602619}
|
||||
- component: {fileID: 1387587181254949733}
|
||||
m_Layer: 0
|
||||
m_Name: AreaTouchCam
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3488899534283412697
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1907375868528687128}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3233441867675090637}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7907247812297230186
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1907375868528687128}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &4758101108332602619
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1907375868528687128}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 0}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!114 &1387587181254949733
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1907375868528687128}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: cbda204e0e5552e4692f0f5e234f062d, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_cinemachineCamera: {fileID: 0}
|
||||
orbital: {fileID: 0}
|
||||
minSwipeDistance: 10
|
||||
speedX: 300
|
||||
speedY: 500
|
||||
--- !u!1 &2486392142327362049
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -30,7 +123,8 @@ RectTransform:
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Children:
|
||||
- {fileID: 3488899534283412697}
|
||||
m_Father: {fileID: 2780428059708698453}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
@@ -59,7 +153,7 @@ Canvas:
|
||||
m_AdditionalShaderChannelsFlag: 0
|
||||
m_UpdateRectTransformForStandalone: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 100
|
||||
m_SortingOrder: -1
|
||||
m_TargetDisplay: 0
|
||||
--- !u!114 &1184637750286334292
|
||||
MonoBehaviour:
|
||||
@@ -152,3 +246,4 @@ MonoBehaviour:
|
||||
currentTargetNPCID: 0
|
||||
dialogResouce: {fileID: 11400000, guid: 540bc8e61556ba4479407a2d68e17580, type: 2}
|
||||
canvasDlg: {fileID: 7894129013412138377}
|
||||
cDlgQuickBar: {fileID: 0}
|
||||
|
||||
@@ -1,11 +1,45 @@
|
||||
using Unity.Cinemachine;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace BrewMonster
|
||||
{
|
||||
public class CameraController : MonoBehaviour
|
||||
public class CameraController : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
|
||||
{
|
||||
[SerializeField]private CinemachineCamera _cinemachineCamera;
|
||||
[SerializeField]private CinemachineOrbitalFollow orbital;
|
||||
private Vector2 currentPos;
|
||||
private bool fingerDown = false;
|
||||
Vector2 delta = Vector2.zero;
|
||||
public float minSwipeDistance = 10f;
|
||||
public float speedX = 1f;
|
||||
public float speedY = 1f;
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
delta = eventData.position - currentPos;
|
||||
|
||||
if (delta.magnitude >= minSwipeDistance)
|
||||
{
|
||||
orbital.HorizontalAxis.Value += delta.normalized.x * speedX * Time.deltaTime;
|
||||
//orbital.HorizontalAxis.Value = Mathf.Clamp(orbital.HorizontalAxis.Value, -360f, 360f);
|
||||
orbital.VerticalAxis.Value += delta.normalized.y * speedY * Time.deltaTime;
|
||||
orbital.VerticalAxis.Value = Mathf.Clamp(orbital.VerticalAxis.Value, -360f, 360f);
|
||||
}
|
||||
currentPos = eventData.position;
|
||||
}
|
||||
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
currentPos = eventData.position;
|
||||
fingerDown = true;
|
||||
}
|
||||
|
||||
public void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
fingerDown = false;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
//todo: should not always update
|
||||
@@ -13,6 +47,8 @@ namespace BrewMonster
|
||||
{
|
||||
_cinemachineCamera.Follow = CECGameRun.Instance.GetHostPlayer().transform;
|
||||
_cinemachineCamera.ForceCameraPosition(CECGameRun.Instance.GetHostPlayer().transform.position, Quaternion.identity);
|
||||
orbital.HorizontalAxis.Value = 208;
|
||||
orbital.VerticalAxis.Value = -268;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,19 @@ namespace BrewMonster.Scripts
|
||||
DEST_STANDJUMP = 4,
|
||||
DEST_AUTOPF = 5; // Movement type
|
||||
}
|
||||
const float A3D_PI = 3.1415926535f;
|
||||
static float DEG2RAD(float deg) => ((deg) * A3D_PI / 180.0f);
|
||||
static float pitch_ang_wing => DEG2RAD(45.0f);
|
||||
static float pitch_ang_fly_sword => DEG2RAD(25.0f);
|
||||
static float lean_max_ang => DEG2RAD(45.0f);
|
||||
static float ang_vel_fly => 1.0f / DEG2RAD(60.0f);
|
||||
static float ang_vel_swim => 1.0f / DEG2RAD(180.0f);
|
||||
static float pitch_co_wing => pitch_ang_wing / A3D_PI;
|
||||
static float pitch_co_fly_sword => pitch_ang_fly_sword / A3D_PI;
|
||||
const float sidle_co = .5f;
|
||||
static float sidle_co_r => 1.0f - sidle_co;
|
||||
static float push_pitch_vel_wing => pitch_ang_wing / 0.5f;
|
||||
static float push_pitch_vel_fly_sword => pitch_ang_fly_sword / 0.5f;
|
||||
|
||||
private const uint MoveInputMask = 0x0F; // MD_FORWARD | MD_RIGHT | MD_BACK | MD_LEFT
|
||||
|
||||
@@ -865,8 +878,300 @@ namespace BrewMonster.Scripts
|
||||
else
|
||||
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 0, m_vMoveDest, vVel2, iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
|
||||
}
|
||||
else if (m_iDestType == DestTypes.DEST_2D)
|
||||
{
|
||||
Vector3 vPushDir = Vector3.zero;
|
||||
m_pHost.GetPushDir(ref vPushDir, (uint)MOVE_DIR.MD_ALL, 0f);
|
||||
vPushDir.x = vPushDir.z = 0.0f;
|
||||
|
||||
float fSpeed1H = m_pHost.m_vVelocity.MagnitudeH();
|
||||
float fSpeed1V = m_pHost.m_vVelocity.y;
|
||||
|
||||
A3DVECTOR3 vMoveDirH = m_vMoveDest - vCurPos;
|
||||
vMoveDirH.y = 0.0f;
|
||||
float fDistH = vMoveDirH.Normalize();
|
||||
|
||||
float pa = 0.0f;
|
||||
|
||||
// Calculate the distance to reduce velocity to 0
|
||||
float s = -0.5f * fSpeed1H * fSpeed1H / na;
|
||||
if (fDistH > s - 0.01f)
|
||||
pa = CECHostMove.EC_PUSH_ACCE;
|
||||
|
||||
float fSpeed2H = fSpeed1H + (pa + na) * fDeltaTime;
|
||||
if (Math.Abs(pa - 0f) < float.Epsilon && fSpeed2H < 0.0f)
|
||||
fSpeed2H = 0.0f; // Only resistance couldn't generate negative speed
|
||||
else if (fSpeed2H > fMaxSpeed)
|
||||
fSpeed2H = fMaxSpeed;
|
||||
|
||||
Glide(fDistH / fMaxSpeed, vMoveDirH, fDeltaTime, bInAir);
|
||||
|
||||
vMoveDirH = m_pHost.GetModelMoveDir();
|
||||
vMoveDirH.y = 0;
|
||||
vMoveDirH.Normalize();
|
||||
|
||||
// Vertical speed
|
||||
float fSpeed2V = CalcFlySwimVertSpeed(fSpeed1V, vPushDir.y, CECHostMove.EC_PUSH_ACCE, fDeltaTime);
|
||||
A3DVECTOR3 vVel2 = vMoveDirH * fSpeed2H + GPDataTypeHelper.g_vAxisY * fSpeed2V;
|
||||
|
||||
// Air/water move
|
||||
vCurPos = m_pHost.m_MoveCtrl.AirWaterMove(vVel2, fDeltaTime, bInAir);
|
||||
|
||||
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
|
||||
{
|
||||
vVel2.Clear();
|
||||
Finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reached destination ?
|
||||
A3DVECTOR3 vMoveDelta = vCurPos - m_pHost.GetPos();
|
||||
vMoveDelta.y = 0.0f;
|
||||
float fMoveDistH = vMoveDelta.Normalize();
|
||||
if (fMoveDistH >= fDistH)
|
||||
{
|
||||
vVel2.x = vVel2.z = 0.0f;
|
||||
if (Math.Abs(vVel2.y - 0f) < float.Epsilon)
|
||||
{
|
||||
Finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_bUseAutoMoveDialog)
|
||||
{
|
||||
Finish();
|
||||
vVel2.y = 0.0f;
|
||||
}
|
||||
|
||||
m_iDestType = DestTypes.DEST_PUSH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
|
||||
m_pHost.m_vVelocity = vVel2;
|
||||
|
||||
if (m_bFinished)
|
||||
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), vVel2.Magnitude(), iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
|
||||
else
|
||||
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 0, m_vMoveDest, vVel2, iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
|
||||
}
|
||||
else if (m_iDestType == DestTypes.DEST_3D)
|
||||
{
|
||||
float fSpeed1 = m_pHost.m_vVelocity.Magnitude();
|
||||
A3DVECTOR3 vMoveDir = m_vMoveDest - vCurPos;
|
||||
float fDist = vMoveDir.Normalize();
|
||||
|
||||
float pa = 0.0f;
|
||||
|
||||
// Calculate the distance to reduce velocity to 0
|
||||
float s = -0.5f * fSpeed1 * fSpeed1 / na;
|
||||
if (fDist > s - 0.01f)
|
||||
pa = CECHostMove.EC_PUSH_ACCE;
|
||||
|
||||
float fSpeed2 = fSpeed1 + (pa + na) * fDeltaTime;
|
||||
if (Math.Abs(pa - 0f) < float.Epsilon && fSpeed2 < 0.0f)
|
||||
fSpeed2 = 0.0f; // Only resistance couldn't generate negative speed
|
||||
|
||||
AAssist.a_Clamp(ref fSpeed2, -fMaxSpeed, fMaxSpeed);
|
||||
|
||||
Vector3 vMoveDirH = new Vector3(vMoveDir.x, 0.0f, vMoveDir.z);
|
||||
if (vMoveDirH != Vector3.zero)
|
||||
{
|
||||
//m_pHost.StartModelMove(vMoveDirH, g_vAxisY, 100);
|
||||
//m_pHost.ChangeModelTargetDirAndUp(vMoveDirH, g_vAxisY);
|
||||
m_pHost.SetRotationHP(vMoveDirH);
|
||||
}
|
||||
|
||||
// Air/water move
|
||||
// A3DVECTOR3 vVel1 = vMoveDir * fSpeed1;
|
||||
A3DVECTOR3 vVel2 = vMoveDir * fSpeed2;
|
||||
vCurPos = m_pHost.m_MoveCtrl.AirWaterMove(vMoveDir, fSpeed2, fDeltaTime, bInAir, false);
|
||||
|
||||
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
|
||||
{
|
||||
vVel2.Clear();
|
||||
Finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reached destination ?
|
||||
A3DVECTOR3 vMoveDelta = vCurPos - m_pHost.GetPos();
|
||||
float fMoveDist = vMoveDelta.Normalize();
|
||||
if (fMoveDist >= fDist)
|
||||
{
|
||||
vVel2.Clear();
|
||||
Finish();
|
||||
m_bUseAutoMoveDialog = false;
|
||||
}
|
||||
}
|
||||
|
||||
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
|
||||
m_pHost.m_vVelocity = vVel2;
|
||||
|
||||
if (m_bFinished)
|
||||
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fMaxSpeed, iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
|
||||
else
|
||||
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 1, m_vMoveDest, vVel2, iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
|
||||
}
|
||||
else if (m_iDestType == DestTypes.DEST_PUSH)
|
||||
{
|
||||
Vector3 vPushDir = Vector3.zero, vUp;
|
||||
bool bPush = m_pHost.GetPushDir(ref vPushDir, (uint)(MOVE_DIR.MD_FORWARD | MOVE_DIR.MD_BACK | MOVE_DIR.MD_LEFT | MOVE_DIR.MD_RIGHT), fDeltaTime);
|
||||
|
||||
if (!bPush)
|
||||
{
|
||||
//vPushDir = m_pHost.GetCameraCoord().GetDir();
|
||||
vPushDir.y = 0;
|
||||
vPushDir.Normalize();
|
||||
}
|
||||
|
||||
int nPitchDir = 0;
|
||||
if ((m_pHost.m_dwMoveRelDir & (int)(MOVE_DIR.MD_LEFT | MOVE_DIR.MD_RIGHT)) == 0)
|
||||
{
|
||||
A3DVECTOR3 vOldDir = m_pHost.GetModelMoveDir();
|
||||
vOldDir.y = 0;
|
||||
vOldDir.Normalize();
|
||||
|
||||
A3DVECTOR3 vNewDir = EC_Utility.ToA3DVECTOR3(vPushDir);
|
||||
vNewDir.y = 0;
|
||||
vNewDir.Normalize();
|
||||
|
||||
float fAngle = A3DVECTOR3.DotProduct(vOldDir, vNewDir);
|
||||
if (fAngle < 1.0f - 1e-4)
|
||||
{
|
||||
A3DVECTOR3 vUp_fAngle = A3DVECTOR3.CrossProduct(vOldDir, vNewDir);
|
||||
if (vUp_fAngle.y > 0) nPitchDir = 1;
|
||||
else nPitchDir = -1;
|
||||
if ((m_pHost.m_dwMoveRelDir & (uint)MOVE_DIR.MD_BACK) != 0)
|
||||
nPitchDir = -nPitchDir;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pHost.m_dwMoveRelDir != 0)
|
||||
{
|
||||
if ((m_pHost.m_dwMoveRelDir & ~(uint)(MOVE_DIR.MD_ABSDOWN | MOVE_DIR.MD_ABSUP)) != 0)
|
||||
{
|
||||
float fPitchDelta = (/*m_pHost.UsingWing()*/m_pHost.GetWingType() == enumWingType.WINGTYPE_WING ? push_pitch_vel_wing : push_pitch_vel_fly_sword) * fDeltaTime;
|
||||
|
||||
if ((m_pHost.m_dwMoveRelDir & (uint)MOVE_DIR.MD_LEFT) != 0 || nPitchDir == -1)
|
||||
{
|
||||
if ((m_pHost.m_dwMoveRelDir & (uint)MOVE_DIR.MD_BACK) != 0)
|
||||
m_fPushPitch -= fPitchDelta;
|
||||
else
|
||||
m_fPushPitch += fPitchDelta;
|
||||
}
|
||||
else if ((m_pHost.m_dwMoveRelDir & (uint)MOVE_DIR.MD_RIGHT) != 0 || nPitchDir == 1)
|
||||
{
|
||||
if ((m_pHost.m_dwMoveRelDir & (uint)MOVE_DIR.MD_BACK) != 0)
|
||||
m_fPushPitch += fPitchDelta;
|
||||
else
|
||||
m_fPushPitch -= fPitchDelta;
|
||||
}
|
||||
else if (m_fPushPitch > fPitchDelta)
|
||||
m_fPushPitch -= fPitchDelta;
|
||||
else if (m_fPushPitch < -fPitchDelta)
|
||||
m_fPushPitch += fPitchDelta;
|
||||
else
|
||||
m_fPushPitch = 0;
|
||||
// TO DO: fix after
|
||||
//A3DVECTOR3 vRight = m_pHost.GetCameraCoord().GetRight();
|
||||
//float fLean = -Math.Asin(m_pHost.GetCameraCoord().GetDir().y);
|
||||
//AAssist.a_Clamp(ref fLean, -lean_max_ang, lean_max_ang);
|
||||
|
||||
//if (Math.Abs(fLean) > DEG2RAD(3.0f))
|
||||
//{
|
||||
// vPushDir = a3d_RotatePosAroundAxis(vPushDir, vRight, fLean);
|
||||
// vUp = a3d_RotatePosAroundAxis(g_vAxisY, vRight, fLean);
|
||||
//}
|
||||
//else
|
||||
// vUp = EC_Utility.ToVector3(GPDataTypeHelper.g_vAxisY);
|
||||
|
||||
//float pitch_ang = /*m_pHost.UsingWing()*/ m_pHost.GetWingType() == enumWingType.WINGTYPE_WING ? pitch_ang_wing : pitch_ang_fly_sword;
|
||||
//AAssist.a_Clamp(ref m_fPushPitch, -pitch_ang, pitch_ang);
|
||||
|
||||
//if (Math.Abs(m_fPushPitch) > DEG2RAD(4.0f))
|
||||
// vUp = a3d_RotatePosAroundAxis(vUp, vPushDir, m_fPushPitch);
|
||||
|
||||
//m_pHost.StartModelMove(vPushDir, vUp, 0);
|
||||
}
|
||||
|
||||
// if (bPush)
|
||||
if (bPush || (m_pHost.m_dwMoveRelDir & (uint)(MOVE_DIR.MD_ABSDOWN | MOVE_DIR.MD_ABSUP)) != 0)
|
||||
{
|
||||
// float pa = bPush ? EC_PUSH_ACCE : 0.0f;
|
||||
float pa = CECHostMove.EC_PUSH_ACCE;
|
||||
float na1 = m_pHost.m_iMoveEnv == (int)MoveEnvironment.MOVEENV_AIR ? CECHostMove.EC_NACCE_AIR : CECHostMove.EC_NACCE_WATER;
|
||||
float fAccel = pa + na1;
|
||||
|
||||
float fSpeed1 = m_pHost.m_vVelocity.Magnitude();
|
||||
float fSpeed2 = fSpeed1 + fAccel * fDeltaTime;
|
||||
AAssist.a_Clamp(ref fSpeed2, 0.0f, fMaxSpeed);
|
||||
|
||||
// Air/water move
|
||||
Vector3 vVelDir = Vector3.zero;
|
||||
if (bPush)
|
||||
vVelDir = vPushDir;
|
||||
|
||||
if ((m_pHost.m_dwMoveRelDir & (uint)MOVE_DIR.MD_ABSDOWN) != 0)
|
||||
{
|
||||
vVelDir += -EC_Utility.ToVector3(GPDataTypeHelper.g_vAxisY);
|
||||
vVelDir.Normalize();
|
||||
}
|
||||
else if ((m_pHost.m_dwMoveRelDir & (uint)MOVE_DIR.MD_ABSUP) != 0)
|
||||
{
|
||||
vVelDir += EC_Utility.ToVector3(GPDataTypeHelper.g_vAxisY);
|
||||
vVelDir.Normalize();
|
||||
}
|
||||
|
||||
// A3DVECTOR3 vVel = vPushDir * fSpeed2;
|
||||
Vector3 vVel = vVelDir * fSpeed2;
|
||||
vCurPos = m_pHost.m_MoveCtrl.AirWaterMove(EC_Utility.ToA3DVECTOR3(vVel), fDeltaTime, bInAir);
|
||||
|
||||
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3)
|
||||
{
|
||||
Finish();
|
||||
m_pHost.m_vVelocity.Clear();
|
||||
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fMaxSpeed, iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
|
||||
if (m_bUseAutoMoveDialog)
|
||||
{
|
||||
m_fAutoHeight = vCurPos.y / 10.0f;
|
||||
}
|
||||
m_pHost.m_vVelocity = EC_Utility.ToA3DVECTOR3(vVel);
|
||||
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 2, GPDataTypeHelper.g_vOrigin, EC_Utility.ToA3DVECTOR3(vVel), iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_bUseAutoMoveDialog)
|
||||
Finish();
|
||||
else
|
||||
m_iDestType = DestTypes.DEST_2D;
|
||||
|
||||
m_fPushPitch = 0;
|
||||
m_pHost.m_vVelocity.Clear();
|
||||
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fMaxSpeed, iMoveMode | (int)GPMoveMode.GP_MOVE_RUN);
|
||||
}
|
||||
}
|
||||
else if (m_iDestType == DestTypes.DEST_STANDJUMP)
|
||||
{
|
||||
// If host player fly off when jumping up, code will go here. In the
|
||||
// case, just stop move work is well.
|
||||
Finish();
|
||||
}
|
||||
else if (IsAutoPF())
|
||||
{
|
||||
//CECIntelligentRoute::Instance().ResetSearch();
|
||||
m_bSwitchTo2D = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Start gliding
|
||||
protected void Glide(float fMoveTime, A3DVECTOR3 vMoveDirH, float fDeltaTime, bool bFly)
|
||||
{
|
||||
|
||||
@@ -53,6 +53,12 @@ namespace BrewMonster.Scripts.Managers
|
||||
private static bool s_hasPendingCash;
|
||||
private static int s_pendingCashAmount;
|
||||
|
||||
// Flags to prevent log spam for extended description warnings
|
||||
// 防止扩展描述警告日志刷屏的标志
|
||||
private static bool m_HasLoggedExtDescNull = false;
|
||||
private static bool m_HasLoggedExtDescNotInit = false;
|
||||
private static bool m_HasLoggedExtDescError = false;
|
||||
|
||||
private InventoryModel model;
|
||||
private InventoryView view;
|
||||
|
||||
@@ -828,16 +834,81 @@ namespace BrewMonster.Scripts.Managers
|
||||
{
|
||||
// Fallback to legacy string-table description if centralised pipeline returns empty
|
||||
string itemDescription = GetItemDescription(item.m_tid);
|
||||
string itemExtendedDesc = GetItemExtendedDescription(item.m_tid);
|
||||
descriptionText?.Set(itemDescription ?? "No description available");
|
||||
extendedDescText?.Set(itemExtendedDesc ?? "");
|
||||
}
|
||||
|
||||
// Get extended description exactly like C++ code: g_pGame->GetItemExtDesc(m_tid)
|
||||
// C++ code doesn't check IsInitialized() - it just calls GetWideString() directly
|
||||
// 完全按照C++代码获取扩展描述:g_pGame->GetItemExtDesc(m_tid)
|
||||
// C++代码不检查IsInitialized() - 它直接调用GetWideString()
|
||||
string szExtDesc = null;
|
||||
try
|
||||
{
|
||||
var itemExtDescTab = EC_Game.GetItemExtDesc();
|
||||
if (itemExtDescTab != null)
|
||||
{
|
||||
// First try to get mapped message ID (like TryGetItemExtDesc does)
|
||||
// 首先尝试获取映射的消息ID(如TryGetItemExtDesc所做)
|
||||
if (EC_Game.TryGetItemMsg(item.m_tid, out int messageId, out int displayMode))
|
||||
{
|
||||
szExtDesc = itemExtDescTab.GetWideString(messageId);
|
||||
}
|
||||
|
||||
// Fallback: direct lookup using tid (exactly like C++: m_ItemExtDesc.GetWideString(tid))
|
||||
// 回退:直接使用tid查找(完全像C++:m_ItemExtDesc.GetWideString(tid))
|
||||
if (string.IsNullOrEmpty(szExtDesc))
|
||||
{
|
||||
szExtDesc = itemExtDescTab.GetWideString(item.m_tid);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
// Only log once to avoid spam
|
||||
// 仅记录一次以避免垃圾日志
|
||||
if (!m_HasLoggedExtDescError)
|
||||
{
|
||||
Debug.LogWarning($"[InventoryUI] Error getting extended description: {ex.Message}");
|
||||
m_HasLoggedExtDescError = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Display extended description if found (exactly like C++ checks: if (!szExtDesc || !szExtDesc[0]))
|
||||
// 如果找到扩展描述则显示(完全像C++检查:if (!szExtDesc || !szExtDesc[0]))
|
||||
string displayText = !string.IsNullOrEmpty(szExtDesc)
|
||||
? szExtDesc.Replace("\\r", "\n")
|
||||
: "";
|
||||
|
||||
// Debug logging to diagnose issues
|
||||
// 调试日志以诊断问题
|
||||
if (string.IsNullOrEmpty(displayText))
|
||||
{
|
||||
Debug.Log($"[InventoryUI] Extended description is empty for tid={item.m_tid}. szExtDesc was null/empty.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"[InventoryUI] Found extended description for tid={item.m_tid}, length={displayText.Length}");
|
||||
}
|
||||
|
||||
// Setup equip and drop buttons
|
||||
SetupEquipButton(package, item);
|
||||
SetupDropButton(package, item);
|
||||
|
||||
// Show panel first
|
||||
// 先显示面板
|
||||
ShowDetailPanel(true);
|
||||
|
||||
// Set text directly - if this causes rebuild issues, we'll use coroutine
|
||||
// 直接设置文本 - 如果这导致重建问题,我们将使用协程
|
||||
if (extendedDescText != null)
|
||||
{
|
||||
extendedDescText.Set(displayText);
|
||||
Debug.Log($"[InventoryUI] Set extended description text, extendedDescText is {(extendedDescText == null ? "null" : "not null")}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[InventoryUI] extendedDescText is null! Check Inspector assignment.");
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupEquipButton(byte package, EC_IvtrItem item)
|
||||
|
||||
@@ -1251,14 +1251,180 @@ namespace BrewMonster.Scripts.Managers
|
||||
m_strDesc += "\n";
|
||||
}
|
||||
|
||||
// Add extend description to description string / 添加扩展描述到描述字符串
|
||||
protected void AddExtDescText()
|
||||
{
|
||||
// Extend description from item_ext_desc.txt via EC_Game
|
||||
string ext = TryGetItemExtDesc();
|
||||
if (!string.IsNullOrEmpty(ext))
|
||||
// Get extended description from item_ext_desc.txt using tid / 使用tid从item_ext_desc.txt获取扩展描述
|
||||
string szExtDesc = TryGetItemExtDesc();
|
||||
// Note: Original C++ had early return commented out / 注意:原始C++代码的早期返回被注释掉了
|
||||
// if (!szExtDesc || !szExtDesc[0])
|
||||
// return;
|
||||
|
||||
m_strDesc += "\\r";
|
||||
|
||||
bool bAddLine = true;
|
||||
// Add special properties description / 添加特殊属性描述
|
||||
var pDescTab = EC_Game.GetItemDesc();
|
||||
// Note: ITEMDESC_COL2_BRIGHTBLUE constant - adjust based on actual string table / 注意:ITEMDESC_COL2_BRIGHTBLUE常量 - 根据实际字符串表调整
|
||||
int green = 1000; // ITEMDESC_COL2_BRIGHTBLUE placeholder - adjust this value
|
||||
|
||||
if (m_iCID != (int)InventoryClassId.ICID_GOBLIN) // goblin does not need to display these special properties / 地精不需要显示这些特殊属性
|
||||
{
|
||||
AddDescText(0, true, ext);
|
||||
// Exact C++ logic: (PROC_NO_USER_TRASH) || (!PROC_BINDING && (PROC_DROPWHENDIE || ...))
|
||||
// 精确的C++逻辑:(PROC_NO_USER_TRASH) || (!PROC_BINDING && (PROC_DROPWHENDIE || ...))
|
||||
if ((m_iProcType & (int)ProcType.PROC_NO_USER_TRASH) != 0
|
||||
|| (!((m_iProcType & (int)ProcType.PROC_BINDING) != 0)
|
||||
&& ((m_iProcType & (int)ProcType.PROC_DROPWHENDIE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_DROPPABLE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_SELLABLE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_TRADEABLE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_DISAPEAR) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_USE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_DEADDROP) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_OFFLINE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_UNREPAIRABLE) != 0)))
|
||||
{
|
||||
bAddLine = false;
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
string szCol = pDescTab.GetWideString(green);
|
||||
if (!string.IsNullOrEmpty(szCol))
|
||||
{
|
||||
m_strDesc += szCol;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: These message IDs are placeholders - adjust based on actual string table / 注意:这些消息ID是占位符 - 根据实际字符串表调整
|
||||
if ((m_iProcType & (int)ProcType.PROC_DROPWHENDIE) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_DEAD_PROTECT placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2000); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_DROPPABLE) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_DROP placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2001); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_SELLABLE) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_TRADE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2002); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_TRADEABLE) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_PLAYER_TRADE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2003); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_DISAPEAR) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_LEAVE_SCENE_DISAPEAR placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2004); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_USE) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_USE_AFTER_PICK_UP placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2005); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_DEADDROP) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_DROP_WHEN_DEAD placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2006); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_OFFLINE) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_DROP_WHEN_OFFLINE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2007); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_UNREPAIRABLE) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_UNREPAIRABLE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2008); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_NO_USER_TRASH) != 0)
|
||||
{
|
||||
m_strDesc += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_USER_TRASH placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2009); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
m_strDesc += desc;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TrimLastReturn();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TrimLastReturn();
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(szExtDesc))
|
||||
return;
|
||||
|
||||
// Extend description is below special properties / 扩展描述在特殊属性下方
|
||||
if (bAddLine)
|
||||
m_strDesc += "\\r\\r";
|
||||
else
|
||||
m_strDesc += "\\r";
|
||||
m_strDesc += szExtDesc;
|
||||
}
|
||||
|
||||
protected void AddExpireTimeDesc()
|
||||
@@ -1402,6 +1568,182 @@ namespace BrewMonster.Scripts.Managers
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get extended description text for UI display.
|
||||
/// This method mirrors AddExtDescText() logic but returns a string instead of modifying m_strDesc.
|
||||
/// 此方法镜像AddExtDescText()逻辑,但返回字符串而不是修改m_strDesc
|
||||
/// </summary>
|
||||
public string GetExtendedDescText()
|
||||
{
|
||||
string result = string.Empty;
|
||||
|
||||
// Get extended description from item_ext_desc.txt using tid / 使用tid从item_ext_desc.txt获取扩展描述
|
||||
string szExtDesc = TryGetItemExtDesc();
|
||||
// Note: Original C++ had early return commented out / 注意:原始C++代码的早期返回被注释掉了
|
||||
// if (!szExtDesc || !szExtDesc[0])
|
||||
// return;
|
||||
|
||||
result += "\\r";
|
||||
|
||||
bool bAddLine = true;
|
||||
// Add special properties description / 添加特殊属性描述
|
||||
var pDescTab = EC_Game.GetItemDesc();
|
||||
// Note: ITEMDESC_COL2_BRIGHTBLUE constant - adjust based on actual string table / 注意:ITEMDESC_COL2_BRIGHTBLUE常量 - 根据实际字符串表调整
|
||||
int green = 1000; // ITEMDESC_COL2_BRIGHTBLUE placeholder - adjust this value
|
||||
|
||||
if (m_iCID != (int)InventoryClassId.ICID_GOBLIN) // goblin does not need to display these special properties / 地精不需要显示这些特殊属性
|
||||
{
|
||||
// Exact C++ logic: (PROC_NO_USER_TRASH) || (!PROC_BINDING && (PROC_DROPWHENDIE || ...))
|
||||
// 精确的C++逻辑:(PROC_NO_USER_TRASH) || (!PROC_BINDING && (PROC_DROPWHENDIE || ...))
|
||||
if ((m_iProcType & (int)ProcType.PROC_NO_USER_TRASH) != 0
|
||||
|| (!((m_iProcType & (int)ProcType.PROC_BINDING) != 0)
|
||||
&& ((m_iProcType & (int)ProcType.PROC_DROPWHENDIE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_DROPPABLE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_SELLABLE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_TRADEABLE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_DISAPEAR) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_USE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_DEADDROP) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_OFFLINE) != 0
|
||||
|| (m_iProcType & (int)ProcType.PROC_UNREPAIRABLE) != 0)))
|
||||
{
|
||||
bAddLine = false;
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
string szCol = pDescTab.GetWideString(green);
|
||||
if (!string.IsNullOrEmpty(szCol))
|
||||
{
|
||||
result += szCol;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: These message IDs are placeholders - adjust based on actual string table / 注意:这些消息ID是占位符 - 根据实际字符串表调整
|
||||
if ((m_iProcType & (int)ProcType.PROC_DROPWHENDIE) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_DEAD_PROTECT placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2000); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_DROPPABLE) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_DROP placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2001); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_SELLABLE) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_TRADE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2002); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_TRADEABLE) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_PLAYER_TRADE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2003); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_DISAPEAR) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_LEAVE_SCENE_DISAPEAR placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2004); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_USE) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_USE_AFTER_PICK_UP placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2005); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_DEADDROP) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_DROP_WHEN_DEAD placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2006); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_OFFLINE) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_DROP_WHEN_OFFLINE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2007); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_UNREPAIRABLE) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_UNREPAIRABLE placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2008); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
if ((m_iProcType & (int)ProcType.PROC_NO_USER_TRASH) != 0)
|
||||
{
|
||||
result += "\\r";
|
||||
if (pDescTab != null && pDescTab.IsInitialized())
|
||||
{
|
||||
// ITEMDESC_NO_USER_TRASH placeholder - adjust this value
|
||||
string desc = pDescTab.GetWideString(2009); // Placeholder ID
|
||||
if (!string.IsNullOrEmpty(desc))
|
||||
result += desc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(szExtDesc))
|
||||
return result;
|
||||
|
||||
// Extend description is below special properties / 扩展描述在特殊属性下方
|
||||
if (bAddLine)
|
||||
result += "\\r\\r";
|
||||
else
|
||||
result += "\\r";
|
||||
result += szExtDesc;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
@@ -363,7 +363,7 @@ namespace BrewMonster {
|
||||
}
|
||||
|
||||
// Air/Water move
|
||||
A3DVECTOR3 AirWaterMove(A3DVECTOR3 vDir, float fSpeed, float fTime, bool bInAir, bool bTrace/* false */)
|
||||
public A3DVECTOR3 AirWaterMove(A3DVECTOR3 vDir, float fSpeed, float fTime, bool bInAir, bool bTrace/* false */)
|
||||
{
|
||||
|
||||
A3DVECTOR3 vRealDir = vDir;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using BrewMonster.Scripts.World;
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Scripts.World;
|
||||
using CSNetwork.GPDataType;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
@@ -11,8 +12,76 @@ namespace BrewMonster.Scripts
|
||||
// Cho phép CECHostMove gán mask theo scene (giữ linh hoạt nhưng không phá cấu trúc)
|
||||
public static LayerMask BrushMask { get; set; } = 1<<7;
|
||||
public static LayerMask TerrainMask { get; set; } = 1<<6;
|
||||
public static LayerMask WaterMask { get; set; } = 1<<8;
|
||||
|
||||
const float LOCAL_EPSILON = 1e-5f;
|
||||
const float FLY_MAX_HEIGHT = 800.0f; // ·ÉÐеÄ×î´ó¸ß¶È£¡
|
||||
|
||||
// change this array when some new submap can go!
|
||||
static uint[,] available_maps =
|
||||
{
|
||||
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 1, 1, 1, 1, 1, 1, 1},
|
||||
{0, 1, 1, 1, 1, 1, 1, 1},
|
||||
{0, 1, 1, 1, 1, 1, 1, 0},
|
||||
{0, 1, 1, 1, 1, 1, 1, 0},
|
||||
{0, 1, 1, 1, 1, 1, 1, 0},
|
||||
{0, 1, 1, 1, 1, 1, 1, 0},
|
||||
{0, 1, 1, 1, 1, 1, 1, 0},
|
||||
{0, 1, 1, 1, 1, 1, 1, 0},
|
||||
{0, 0, 0, 0, 0, 1, 1, 0},
|
||||
{1, 1, 0, 0, 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static uint[,] available_maps4x4 =
|
||||
{
|
||||
{0, 0, 0, 0},
|
||||
{0, 1, 1, 0},
|
||||
{0, 1, 1, 0},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static uint[,] available_maps3x3 =
|
||||
{
|
||||
{0, 0, 0},
|
||||
{0, 1, 0},
|
||||
{0, 0, 0},
|
||||
};
|
||||
|
||||
static uint[,] available_maps2x2 =
|
||||
{
|
||||
{1, 1},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static uint[,] available_maps_137 =
|
||||
{
|
||||
{0, 0, 0, 0, 0, 0},
|
||||
{0, 1, 1, 1, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static uint[,] available_maps_161=
|
||||
{
|
||||
{0, 0, 0, 0},
|
||||
{0, 1, 1, 0},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static uint[,] available_maps_162 =
|
||||
{
|
||||
{0, 0, 0, 0},
|
||||
{0, 1, 1, 0},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
static uint[,] available_maps_163 =
|
||||
{
|
||||
{0, 0, 0, 0},
|
||||
{0, 1, 1, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
//[Flags]
|
||||
public class CDR_EVN
|
||||
@@ -22,7 +91,7 @@ namespace BrewMonster.Scripts
|
||||
CDR_WATER = 0x4;
|
||||
}
|
||||
|
||||
static LayerMask UsedMask_Ground() => BrushMask | TerrainMask;
|
||||
static LayerMask UsedMask_Ground() => BrushMask | TerrainMask | WaterMask;
|
||||
|
||||
static bool CollideWithEnv(env_trace_t pEnvTrc)
|
||||
{
|
||||
@@ -569,13 +638,195 @@ namespace BrewMonster.Scripts
|
||||
|
||||
static void AirMove(ref ON_AIR_CDR_INFO awmInfo)
|
||||
{
|
||||
float DIST_EPSILON = 1e-4f;
|
||||
int MAX_TRY = 1;
|
||||
float VEL_REFLECT = 0.0f;
|
||||
float fTime = awmInfo.t;
|
||||
//@todo : is it necessary to clamp the speed? By Kuiwu[20/9/2005]
|
||||
float fSpeed = awmInfo.fSpeed;
|
||||
if (fSpeed * fTime < DIST_EPSILON)
|
||||
{
|
||||
//@todo : set the output param. By Kuiwu[20/9/2005]
|
||||
return;
|
||||
}
|
||||
|
||||
A3DVECTOR3 vStart = new A3DVECTOR3(awmInfo.vCenter);
|
||||
A3DVECTOR3 vExt = new A3DVECTOR3(awmInfo.vExtent);
|
||||
A3DVECTOR3 vVelDir = new A3DVECTOR3(awmInfo.vVelDir);
|
||||
float dtp = 0f;
|
||||
A3DVECTOR3 vVelocity = new A3DVECTOR3(vVelDir* fSpeed);
|
||||
|
||||
if ((dtp = A3DVECTOR3.DotProduct(vVelDir, awmInfo.vTPNormal)) < 0.0f)
|
||||
{
|
||||
|
||||
//vVelocity = (vVelDir - awmInfo.vTPNormal * dtp - awmInfo.vTPNormal*dtp * 0.01f) * fSpeed;
|
||||
vVelocity = (vVelDir - awmInfo.vTPNormal * dtp) * fSpeed;
|
||||
}
|
||||
|
||||
A3DVECTOR3 vDelta = new A3DVECTOR3(vVelocity* fTime),
|
||||
vNormal = new A3DVECTOR3(),
|
||||
vFinalPos = new A3DVECTOR3(vStart);
|
||||
int nTry = 0;
|
||||
bool bClear = true;
|
||||
env_trace_t trcInfo;
|
||||
trcInfo.bWaterSolid = true;
|
||||
trcInfo.dwCheckFlag = CDR_EVN.CDR_TERRAIN | CDR_EVN.CDR_BRUSH | CDR_EVN.CDR_WATER;
|
||||
trcInfo.vExt = vExt;
|
||||
RaycastHit hit;
|
||||
while (nTry < MAX_TRY)
|
||||
{
|
||||
if (vDelta.SquaredMagnitude() < DIST_EPSILON)
|
||||
{
|
||||
break;
|
||||
}
|
||||
trcInfo.vStart = vStart;
|
||||
trcInfo.vDelta = vDelta;
|
||||
trcInfo.vTerStart = vStart;
|
||||
trcInfo.vTerStart.y -= vExt.y;
|
||||
trcInfo.vWatStart = vStart;
|
||||
trcInfo.vWatStart.y -= vExt.y;
|
||||
//bClear = !CollideWithEnv(&trcInfo);
|
||||
bClear = !Physics.BoxCast(EC_Utility.ToVector3(vStart),
|
||||
EC_Utility.ToVector3(vExt),
|
||||
EC_Utility.ToVector3(vStart + vVelDir).normalized,
|
||||
out hit,
|
||||
Quaternion.identity,
|
||||
EC_Utility.ToVector3(vDelta).magnitude,
|
||||
UsedMask_Ground());
|
||||
++nTry;
|
||||
if (bClear)
|
||||
{
|
||||
vFinalPos = vStart + vDelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
vFinalPos = EC_Utility.ToA3DVECTOR3(hit.point);
|
||||
vNormal = EC_Utility.ToA3DVECTOR3(hit.normal);
|
||||
}
|
||||
//vStart += vDelta * trcInfo.fFraction;
|
||||
//vFinalPos = vStart;
|
||||
//fTime -= fTime * trcInfo.fFraction;
|
||||
//vNormal = trcInfo.vHitNormal;
|
||||
//fSpeed = A3DVECTOR3.Normalize(vVelocity,out vVelDir);
|
||||
//fSpeed *= (1 - nTry * 0.1f);
|
||||
//dtp = A3DVECTOR3.DotProduct(vNormal, vVelDir);
|
||||
//vVelocity = (vVelDir - vNormal * dtp - vNormal * dtp * VEL_REFLECT) * fSpeed;
|
||||
//vDelta = vVelocity * fTime;
|
||||
|
||||
}
|
||||
|
||||
//@note : prevent moving to the invalid area. By Kuiwu[20/9/2005]
|
||||
if (!IsPosInAvailableMap(vFinalPos))
|
||||
{
|
||||
//@todo : set some flag to notify the caller? By Kuiwu[20/9/2005]
|
||||
return;
|
||||
}
|
||||
//too high
|
||||
if (vFinalPos.y > FLY_MAX_HEIGHT - 2.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//see if meet height thresh
|
||||
Vector3 posVStart = EC_Utility.ToVector3(vFinalPos);
|
||||
float fDeltaY = awmInfo.fHeightThresh + 0.1f;
|
||||
|
||||
if (!Physics.Raycast(posVStart,
|
||||
(posVStart + Vector3.down * fDeltaY).normalized,
|
||||
out hit,
|
||||
fDeltaY,
|
||||
UsedMask_Ground()))
|
||||
{
|
||||
awmInfo.vCenter = vFinalPos;
|
||||
awmInfo.vTPNormal = vNormal;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
vFinalPos = EC_Utility.ToA3DVECTOR3(hit.point);
|
||||
vNormal = EC_Utility.ToA3DVECTOR3(hit.normal);
|
||||
awmInfo.vCenter = vFinalPos;
|
||||
awmInfo.vTPNormal = vNormal;
|
||||
}
|
||||
}
|
||||
|
||||
static void WaterMove(ref ON_AIR_CDR_INFO awmInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Note by wenfeng, 05-09-16
|
||||
// This function is only for the Big world but not applicable for the
|
||||
// Instance world!
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static bool IsPosInAvailableMap(A3DVECTOR3 vPos)
|
||||
{
|
||||
float x, z;
|
||||
int su, sv;
|
||||
|
||||
//bool bFlag = true;
|
||||
CECWorld pWorld = EC_Game.GetGameRun().GetWorld();
|
||||
if(pWorld != null)
|
||||
{
|
||||
int idInst = pWorld.GetInstanceID();
|
||||
CECInstance pInst = EC_Game.GetGameRun().GetInstance(idInst);
|
||||
if (pInst == null)
|
||||
return false;
|
||||
|
||||
x = vPos.x + pInst.GetColNum() * 512.0f;
|
||||
z = pInst.GetRowNum() * 512.0f - vPos.z;
|
||||
su = (int) (x / 1024.0f);
|
||||
sv = (int) (z / 1024.0f);
|
||||
|
||||
if (su >= pInst.GetColNum() || su< 0 ||
|
||||
|
||||
sv >= pInst.GetRowNum() || sv< 0)
|
||||
return false;
|
||||
|
||||
switch (idInst)
|
||||
{
|
||||
case 1:
|
||||
return available_maps[sv, su] != 0 && vPos.x <= 3877.0f; // ½ûÖ¹ëÊ×åÁÙ½ü¿´µ½µØÍ¼±ßÔµ
|
||||
|
||||
case 121:
|
||||
case 122:
|
||||
|
||||
return available_maps4x4[sv, su] != 0? true : false;
|
||||
|
||||
case 118:
|
||||
case 119:
|
||||
case 120:
|
||||
case 123:
|
||||
case 125:
|
||||
|
||||
return available_maps3x3[sv, su] != 0? true : false;
|
||||
|
||||
case 134:
|
||||
|
||||
return available_maps2x2[sv, su] != 0 ? true : false;
|
||||
|
||||
case 137:
|
||||
return available_maps_137[sv, su] != 0 ? true : false;
|
||||
|
||||
case 161:
|
||||
return available_maps_161[sv, su] != 0;
|
||||
|
||||
case 162:
|
||||
return available_maps_162[sv, su] != 0 ? true : false;
|
||||
|
||||
case 163:
|
||||
return available_maps_163[sv, su] != 0 ? true : false;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public struct OtherPlayer_Move_Info
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@ using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
using PerfectWorld.Scripts.Shop;
|
||||
using PerfectWorld.Scripts.Managers;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using BrewMonster.Network;
|
||||
using CSNetwork.C2SCommand;
|
||||
@@ -13,10 +14,9 @@ using CSNetwork.C2SCommand;
|
||||
public class NPCShopDetailPanel : MonoBehaviour
|
||||
{
|
||||
[Header("UI Components")]
|
||||
public TextMeshProUGUI itemNameText;
|
||||
public TextMeshProUGUI itemDescriptionText;
|
||||
public TextOutlet itemDescriptionText;
|
||||
public Image itemIconImage;
|
||||
public TextMeshProUGUI itemPriceText;
|
||||
//public TextMeshProUGUI itemPriceText;
|
||||
|
||||
[Header("Action Buttons")]
|
||||
public Button closeButton;
|
||||
@@ -55,15 +55,11 @@ public class NPCShopDetailPanel : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
// Set item name
|
||||
if (itemNameText != null)
|
||||
itemNameText.text = currentItem.name;
|
||||
|
||||
// Set item description
|
||||
if (itemDescriptionText != null)
|
||||
{
|
||||
string description = GetItemDescription((int)currentItem.id);
|
||||
itemDescriptionText.text = description;
|
||||
itemDescriptionText.Set(description);
|
||||
}
|
||||
|
||||
// Set price (use first available price)
|
||||
@@ -80,8 +76,8 @@ public class NPCShopDetailPanel : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
if (itemPriceText != null)
|
||||
itemPriceText.text = price > 0 ? $"Price: {price}" : "Price: N/A";
|
||||
// if (itemPriceText != null)
|
||||
// itemPriceText.text = price > 0 ? $"Price: {price}" : "Price: N/A";
|
||||
|
||||
// Load icon
|
||||
if (itemIconImage != null)
|
||||
@@ -114,7 +110,7 @@ public class NPCShopDetailPanel : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
string GetItemDescription(int itemId)
|
||||
string GetItemDescription(int itemId)
|
||||
{
|
||||
// First check if description is already in the item data
|
||||
if (!string.IsNullOrEmpty(currentItem.desc))
|
||||
@@ -122,27 +118,48 @@ public class NPCShopDetailPanel : MonoBehaviour
|
||||
return currentItem.desc;
|
||||
}
|
||||
|
||||
// Otherwise, build description using the same central pipeline as inventory:
|
||||
try
|
||||
// Try to use EC_IvtrEquip description for equipment items (like EC_InventoryUI does)
|
||||
try
|
||||
{
|
||||
// Create EC_IvtrEquip for equipment items - this will work for weapons and armor
|
||||
EC_IvtrEquip equipment = new EC_IvtrEquip(itemId, 0);
|
||||
|
||||
// For NPC shop items, we typically have static data only
|
||||
// Try to get description using GetNormalDesc() which works with base stats
|
||||
string equipDesc = equipment.GetNormalDesc();
|
||||
if (!string.IsNullOrEmpty(equipDesc))
|
||||
{
|
||||
EC_IvtrItem item = EC_IvtrItem.CreateItem(itemId, 0, 1);
|
||||
if (item != null)
|
||||
// Replace C++ style "\r" line separators with real newlines for TMP
|
||||
return equipDesc.Replace("\\r", "\n");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
// If EC_IvtrEquip fails, fall through to EC_IvtrItem method
|
||||
Debug.LogWarning($"[NPCShopDetailPanel] Failed to get equipment description for item {itemId}: {ex.Message}");
|
||||
}
|
||||
|
||||
// Fallback: build description using EC_IvtrItem (for non-equipment items)
|
||||
try
|
||||
{
|
||||
EC_IvtrItem item = EC_IvtrItem.CreateItem(itemId, 0, 1);
|
||||
if (item != null)
|
||||
{
|
||||
// For NPC shop, we typically have static data only, so load from local DB
|
||||
item.GetDetailDataFromLocal();
|
||||
string description = item.GetDesc();
|
||||
if (!string.IsNullOrEmpty(description))
|
||||
{
|
||||
// For NPC shop, we typically have static data only, so load from local DB
|
||||
item.GetDetailDataFromLocal();
|
||||
string description = item.GetDesc();
|
||||
if (!string.IsNullOrEmpty(description))
|
||||
{
|
||||
return description.Replace("\\r", "\n");
|
||||
}
|
||||
return description.Replace("\\r", "\n");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[NPCShopDetailPanel] Failed to get description for item {itemId}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[NPCShopDetailPanel] Failed to get description for item {itemId}: {ex.Message}");
|
||||
}
|
||||
|
||||
return "No description available.";
|
||||
return "No description available.";
|
||||
}
|
||||
|
||||
void OnCloseClicked()
|
||||
@@ -197,5 +214,25 @@ public class NPCShopDetailPanel : MonoBehaviour
|
||||
if (buyButton != null)
|
||||
buyButton.onClick.RemoveListener(OnBuyButtonClicked);
|
||||
}
|
||||
|
||||
// === Text Outlet Helper ===
|
||||
[System.Serializable]
|
||||
public class TextOutlet
|
||||
{
|
||||
[SerializeField] public Text legacy;
|
||||
[SerializeField] public TMPro.TextMeshProUGUI tmp;
|
||||
|
||||
public void Set(string value)
|
||||
{
|
||||
if (legacy != null)
|
||||
{
|
||||
legacy.text = EC_Utility.FormatForLegacyText(value ?? string.Empty);
|
||||
}
|
||||
if (tmp != null)
|
||||
{
|
||||
tmp.text = EC_Utility.FormatForTextMeshPro(value ?? string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
using System;
|
||||
using BrewMonster.Network;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
|
||||
public class ShopDetailPanel : MonoBehaviour
|
||||
{
|
||||
@@ -75,8 +78,10 @@ public class ShopDetailPanel : MonoBehaviour
|
||||
itemNameText.text = currentItem.name;
|
||||
|
||||
if (itemDescriptionText != null)
|
||||
itemDescriptionText.text = currentItem.desc;
|
||||
|
||||
{
|
||||
RemoveCaretColor(itemDescriptionText.text = ConvertColorCodeOfText(currentItem.desc));
|
||||
}
|
||||
|
||||
if (itemQuantityText != null)
|
||||
itemQuantityText.text = $"Quantity: {currentItem.num}";
|
||||
|
||||
@@ -84,6 +89,12 @@ public class ShopDetailPanel : MonoBehaviour
|
||||
Debug.Log($"[ShopDetailPanel] About to load icon. itemIconImage is null: {itemIconImage == null}");
|
||||
Debug.Log($"[ShopDetailPanel] Current item icon field: '{currentItem.icon}'");
|
||||
|
||||
if (itemPriceText != null)
|
||||
{
|
||||
itemPriceText.text = currentItem.buy[0].price.ToString();
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(itemPriceText.transform as RectTransform);
|
||||
}
|
||||
|
||||
if (itemIconImage != null)
|
||||
{
|
||||
LoadItemIcon(itemIconImage, currentItem.icon);
|
||||
@@ -99,7 +110,93 @@ public class ShopDetailPanel : MonoBehaviour
|
||||
// Update gift info
|
||||
UpdateGiftInfo();
|
||||
}
|
||||
|
||||
struct ColorText
|
||||
{
|
||||
public string hex;
|
||||
public string content;
|
||||
}
|
||||
private string ConvertColorCodeOfText(string input)
|
||||
{
|
||||
/*string returnValue = "";
|
||||
List<ColorText> colorTexts = new List<ColorText>();
|
||||
ColorText currentColorText = new ColorText();
|
||||
currentColorText.hex = "ffffff";
|
||||
currentColorText.content = "";
|
||||
for (int i = 0; i < input.Length; i++)
|
||||
{
|
||||
if (input[i] == '^' && i + 6 < input.Length)
|
||||
{
|
||||
// Store the current segment before changing color
|
||||
colorTexts.Add(currentColorText);
|
||||
|
||||
// Start a new color segment
|
||||
currentColorText = new ColorText();
|
||||
currentColorText.hex = input.Substring(i + 1, 6);
|
||||
currentColorText.content = "";
|
||||
i += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentColorText.content += input[i];
|
||||
}
|
||||
}
|
||||
foreach ( var ct in colorTexts)
|
||||
{
|
||||
if (ct.hex.ToLower() != "ffffff")
|
||||
{
|
||||
returnValue += $"<color=#{ct.hex}>{ct.content}</color>";
|
||||
}
|
||||
else
|
||||
{
|
||||
returnValue += ct.content;
|
||||
}
|
||||
Debug.Log($"[ShopDetailPanel] Processed ColorText: Hex='{ct.hex}', Content='{ct.content}'");
|
||||
}
|
||||
|
||||
return returnValue;*/
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(input))
|
||||
return input;
|
||||
|
||||
input = input.Replace("\\r\\n", "\n");
|
||||
input = input.Replace("\\r", "\n");
|
||||
input = input.Replace("\\n", "\n");
|
||||
|
||||
input = input.Replace("\r\n", "\n");
|
||||
input = input.Replace("\r", "\n");
|
||||
input = input.Replace("\n", "\n");
|
||||
|
||||
System.Text.StringBuilder sb = new System.Text. StringBuilder();
|
||||
for (int i = 0; i < input.Length; i++)
|
||||
{
|
||||
|
||||
if (input[i] == '^' && i + 6 < input.Length)
|
||||
{
|
||||
string hex = input.Substring(i + 1, 6);
|
||||
if (hex.ToLower() != "ffffff")
|
||||
{
|
||||
sb.Append($"<color=#{hex}>");
|
||||
}
|
||||
i += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(input[i]);
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append("</color>");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string RemoveCaretColor(string input)
|
||||
{
|
||||
return System.Text.RegularExpressions.Regex.Replace(input, @"\^[0-9a-fA-F]{6}", "");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void UpdateBuyOptions()
|
||||
{
|
||||
for (int i = 0; i < buyOptionButtons.Length && i < currentItem.buy.Length; i++)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa133c544a1b54b10bf7c8ab30d9dd6f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,92 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
using System;
|
||||
|
||||
public class SubTypeButton : MonoBehaviour
|
||||
{
|
||||
public TextMeshProUGUI subTypeText;
|
||||
public Button subTypeButton;
|
||||
public Action<SubTypeButton> onSetActive;
|
||||
private ShopUIManager shopUIManager;
|
||||
private string subTypeName;
|
||||
|
||||
[Header("Button Images")]
|
||||
[SerializeField]
|
||||
private Sprite activeSprite;
|
||||
[SerializeField]
|
||||
private Sprite inactiveSprite;
|
||||
[SerializeField]
|
||||
private Image subTypeImage;
|
||||
public void OnClick()
|
||||
{
|
||||
if (shopUIManager != null && !string.IsNullOrEmpty(subTypeName))
|
||||
{
|
||||
shopUIManager.SetSubTypeFilterByName(subTypeName);
|
||||
onSetActive?.Invoke(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnClickAll()
|
||||
{
|
||||
if (shopUIManager != null)
|
||||
{
|
||||
shopUIManager.SetSubTypeFilter(-1);
|
||||
onSetActive?.Invoke(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetButton(string text, ShopUIManager manager)
|
||||
{
|
||||
Debug.Log("SetButton: " + text);
|
||||
subTypeText.text = text;
|
||||
subTypeName = text;
|
||||
shopUIManager = manager;
|
||||
name = text;
|
||||
|
||||
// Setup click listener
|
||||
subTypeButton.onClick.RemoveAllListeners();
|
||||
subTypeButton.onClick.AddListener(OnClick);
|
||||
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
public void SetAllButton(ShopUIManager manager)
|
||||
{
|
||||
Debug.Log("SetAllButton: Tat ca");
|
||||
subTypeText.text = "Tat ca";
|
||||
subTypeName = ""; // Empty for "All" button
|
||||
shopUIManager = manager;
|
||||
name = "Tat ca";
|
||||
|
||||
// Setup click listener to set filter to -1
|
||||
subTypeButton.onClick.RemoveAllListeners();
|
||||
subTypeButton.onClick.AddListener(OnClickAll);
|
||||
|
||||
gameObject.SetActive(true);
|
||||
SetImageActive(this);
|
||||
}
|
||||
|
||||
public void ResetButton()
|
||||
{
|
||||
Debug.Log("ResetButton: " + name);
|
||||
subTypeButton.onClick.RemoveAllListeners();
|
||||
subTypeText.text = "";
|
||||
subTypeName = "";
|
||||
shopUIManager = null;
|
||||
name = "";
|
||||
SetImageActive(null);
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
public void SetImageActive(SubTypeButton button)
|
||||
{
|
||||
if (button == this)
|
||||
{
|
||||
subTypeImage.sprite = activeSprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
subTypeImage.sprite = inactiveSprite;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 926fe0d5d0a764271a3b764afbaf9abc
|
||||
@@ -0,0 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
|
||||
public class SubTypeShop : MonoBehaviour
|
||||
{
|
||||
public SubTypeButton subTypePrefab;
|
||||
public List<SubTypeButton> subTypeButtons;
|
||||
|
||||
|
||||
public void GenerateSubTypeShop(List<string> subTypeNames, ShopUIManager shopUIManager)
|
||||
{
|
||||
ResetSubTypeShop();
|
||||
|
||||
// Always add "Tat ca" (All) button first
|
||||
SubTypeButton allButton = subTypeButtons.Find(b => !b.gameObject.activeSelf);
|
||||
if (allButton == null)
|
||||
{
|
||||
allButton = Instantiate(subTypePrefab, transform);
|
||||
subTypeButtons.Add(allButton);
|
||||
}
|
||||
allButton.SetAllButton(shopUIManager);
|
||||
allButton.onSetActive += SetImageActive;
|
||||
|
||||
// Add other subType buttons
|
||||
foreach (string subType in subTypeNames)
|
||||
{
|
||||
//get unactive from list subTypeButtons first
|
||||
SubTypeButton button = subTypeButtons.Find(b => !b.gameObject.activeSelf);
|
||||
if (button == null)
|
||||
{
|
||||
button = Instantiate(subTypePrefab, transform);
|
||||
subTypeButtons.Add(button);
|
||||
|
||||
}
|
||||
button.SetButton(subType, shopUIManager);
|
||||
button.onSetActive += SetImageActive;
|
||||
}
|
||||
}
|
||||
public void ResetSubTypeShop()
|
||||
{
|
||||
foreach (SubTypeButton button in subTypeButtons)
|
||||
{
|
||||
button.ResetButton();
|
||||
button.onSetActive -= SetImageActive;
|
||||
}
|
||||
}
|
||||
public void SetImageActive(SubTypeButton activeButton)
|
||||
{
|
||||
foreach (SubTypeButton button in subTypeButtons)
|
||||
{
|
||||
button.SetImageActive(activeButton);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80f96f49ed74549a6adce89d44aebb4e
|
||||
@@ -11,7 +11,7 @@ public class ShopUIManager : MonoBehaviour
|
||||
[Header("UI Panels")]
|
||||
public GameObject shopMainPanel;
|
||||
public GameObject shopDetailPanel;
|
||||
|
||||
public GameObject subTypeShopPanel;
|
||||
[Header("Item Display")]
|
||||
public Transform itemContainer; // Parent for item panels
|
||||
public GameObject itemPanelPrefab; // Prefab for individual item panels
|
||||
@@ -31,14 +31,18 @@ public class ShopUIManager : MonoBehaviour
|
||||
public TextMeshProUGUI detailItemQuantity;
|
||||
public Button buyButton;
|
||||
public Button closeDetailButton;
|
||||
|
||||
public ScrollRect detailScrollRect;
|
||||
|
||||
[Header("Main Panel Components")]
|
||||
public Button closeShopButton;
|
||||
|
||||
private List<GameObject> currentItemPanels = new List<GameObject>();
|
||||
private GShopItem selectedItem;
|
||||
private int currentCategory = 0; // 0-5 for the 6 merged categories
|
||||
|
||||
[Header("Sub Type Shop")]
|
||||
//-1 means all sub types
|
||||
public SubTypeShop subTypeShop;
|
||||
private int currentSubType = -1;
|
||||
void Start()
|
||||
{
|
||||
InitializeUI();
|
||||
@@ -65,6 +69,8 @@ public class ShopUIManager : MonoBehaviour
|
||||
shopMainPanel.SetActive(false);
|
||||
if (shopDetailPanel != null)
|
||||
shopDetailPanel.SetActive(false);
|
||||
if (subTypeShop != null)
|
||||
subTypeShopPanel.SetActive(false);
|
||||
}
|
||||
|
||||
void SetupEventListeners()
|
||||
@@ -148,7 +154,6 @@ public class ShopUIManager : MonoBehaviour
|
||||
|
||||
// Get items for current category
|
||||
List<GShopItem> categoryItems = GetItemsForCategory(currentCategory);
|
||||
|
||||
// Create item panels using pooling
|
||||
int siblingIndexCounter = 0;
|
||||
foreach (GShopItem item in categoryItems)
|
||||
@@ -156,9 +161,52 @@ public class ShopUIManager : MonoBehaviour
|
||||
CreateItemPanelFromPool(item, siblingIndexCounter);
|
||||
siblingIndexCounter++;
|
||||
}
|
||||
|
||||
List<string> subTypeNames = GetSubTypeNamesForCategory(currentCategory);
|
||||
currentSubType = -1;
|
||||
subTypeShopPanel.SetActive(subTypeNames.Count > 0);
|
||||
if (subTypeShop != null)
|
||||
subTypeShop.GenerateSubTypeShop(subTypeNames, this);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void SetSubTypeFilter(int subTypeIndex)
|
||||
{
|
||||
currentSubType = subTypeIndex;
|
||||
ApplySubTypeFilter();
|
||||
}
|
||||
|
||||
List<GShopItem> GetItemsForCategory(int categoryIndex)
|
||||
public void SetSubTypeFilterByName(string subTypeName)
|
||||
{
|
||||
int subTypeIndex = GetSubTypeIndexFromName(subTypeName);
|
||||
SetSubTypeFilter(subTypeIndex);
|
||||
}
|
||||
|
||||
public void ApplySubTypeFilter()
|
||||
{
|
||||
ReturnAllPanelsToPool();
|
||||
|
||||
if (shopLoader == null || shopLoader.primaryShop == null)
|
||||
{
|
||||
Debug.LogWarning("ShopLoader or primary shop data not available");
|
||||
return;
|
||||
}
|
||||
if(currentSubType == -1)
|
||||
{
|
||||
RefreshShopDisplay();
|
||||
return;
|
||||
}
|
||||
List<GShopItem> categoryItems = GetItemsForCategory(currentCategory, currentSubType);
|
||||
int siblingIndexCounter = 0;
|
||||
foreach (GShopItem item in categoryItems)
|
||||
{
|
||||
CreateItemPanelFromPool(item, siblingIndexCounter);
|
||||
siblingIndexCounter++;
|
||||
}
|
||||
}
|
||||
List<GShopItem> GetItemsForCategory(int categoryIndex, int subTypeIndex=-1)
|
||||
{
|
||||
List<GShopItem> items = new List<GShopItem>();
|
||||
|
||||
@@ -169,13 +217,51 @@ public class ShopUIManager : MonoBehaviour
|
||||
{
|
||||
if (IsItemInCategory(item, categoryIndex))
|
||||
{
|
||||
items.Add(item);
|
||||
if(IsItemInSubType(item, subTypeIndex))
|
||||
{
|
||||
items.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
List<string> GetSubTypeNamesForCategory(int categoryIndex)
|
||||
{
|
||||
List<string> subTypeNames = new List<string>();
|
||||
|
||||
if (shopLoader?.primaryShop?.mainTypes == null)
|
||||
return subTypeNames;
|
||||
|
||||
// Use the same mapping as IsItemInCategory: 0=0, 1=2, 2=5, 3=1+3+4, 4=6, 5=7
|
||||
List<int> mainTypeIndices = new List<int>();
|
||||
switch (categoryIndex)
|
||||
{
|
||||
case 0: mainTypeIndices.Add(0); break;
|
||||
case 1: mainTypeIndices.Add(2); break;
|
||||
case 2: mainTypeIndices.Add(5); break;
|
||||
case 3: mainTypeIndices.Add(1); mainTypeIndices.Add(3); mainTypeIndices.Add(4); break;
|
||||
case 4: mainTypeIndices.Add(6); break;
|
||||
case 5: mainTypeIndices.Add(7); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
foreach (int mainTypeIndex in mainTypeIndices)
|
||||
{
|
||||
if (mainTypeIndex >= 0 && mainTypeIndex < shopLoader.primaryShop.mainTypes.Count)
|
||||
{
|
||||
foreach (string subType in shopLoader.primaryShop.mainTypes[mainTypeIndex].subTypes)
|
||||
{
|
||||
if (!subTypeNames.Contains(subType))
|
||||
{
|
||||
subTypeNames.Add(subType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return subTypeNames;
|
||||
}
|
||||
bool IsItemInCategory(GShopItem item, int categoryIndex)
|
||||
{
|
||||
// Category mapping: 0=1, 1=2, 2=1+3+4, 3=6, 4=7, 5=8
|
||||
@@ -190,7 +276,89 @@ public class ShopUIManager : MonoBehaviour
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
bool IsItemInSubType(GShopItem item, int combinedSubTypeIndex)
|
||||
{
|
||||
if(combinedSubTypeIndex == -1)
|
||||
return true;
|
||||
|
||||
// Get the subType name for this item's mainType and subType index
|
||||
if (shopLoader?.primaryShop?.mainTypes == null)
|
||||
return false;
|
||||
|
||||
if (item.mainType < 0 || item.mainType >= shopLoader.primaryShop.mainTypes.Count)
|
||||
return false;
|
||||
|
||||
var mainType = shopLoader.primaryShop.mainTypes[item.mainType];
|
||||
if (item.subType < 0 || item.subType >= mainType.subTypes.Count)
|
||||
return false;
|
||||
|
||||
string itemSubTypeName = mainType.subTypes[item.subType];
|
||||
|
||||
// Get the subType name for the filter index
|
||||
string filterSubTypeName = GetSubTypeNameFromIndex(combinedSubTypeIndex);
|
||||
|
||||
return itemSubTypeName == filterSubTypeName;
|
||||
}
|
||||
|
||||
int GetSubTypeIndexFromName(string subTypeName)
|
||||
{
|
||||
if (shopLoader?.primaryShop?.mainTypes == null || string.IsNullOrEmpty(subTypeName))
|
||||
return -1;
|
||||
|
||||
// Find the subType name in the current category's mainTypes
|
||||
List<int> mainTypeIndices = new List<int>();
|
||||
switch (currentCategory)
|
||||
{
|
||||
case 0: mainTypeIndices.Add(0); break;
|
||||
case 1: mainTypeIndices.Add(2); break;
|
||||
case 2: mainTypeIndices.Add(5); break;
|
||||
case 3: mainTypeIndices.Add(1); mainTypeIndices.Add(3); mainTypeIndices.Add(4); break;
|
||||
case 4: mainTypeIndices.Add(6); break;
|
||||
case 5: mainTypeIndices.Add(7); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Find the first matching subType across all relevant mainTypes
|
||||
// We use a combined index: mainTypeIndex * 1000 + subTypeIndex
|
||||
// This allows us to uniquely identify subTypes across different mainTypes
|
||||
foreach (int mainTypeIndex in mainTypeIndices)
|
||||
{
|
||||
if (mainTypeIndex >= 0 && mainTypeIndex < shopLoader.primaryShop.mainTypes.Count)
|
||||
{
|
||||
var mainType = shopLoader.primaryShop.mainTypes[mainTypeIndex];
|
||||
for (int i = 0; i < mainType.subTypes.Count; i++)
|
||||
{
|
||||
if (mainType.subTypes[i] == subTypeName)
|
||||
{
|
||||
// Return a combined index: mainTypeIndex * 1000 + subTypeIndex
|
||||
return mainTypeIndex * 1000 + i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
string GetSubTypeNameFromIndex(int combinedIndex)
|
||||
{
|
||||
if (combinedIndex < 0 || shopLoader?.primaryShop?.mainTypes == null)
|
||||
return null;
|
||||
|
||||
int mainTypeIndex = combinedIndex / 1000;
|
||||
int subTypeIndex = combinedIndex % 1000;
|
||||
|
||||
if (mainTypeIndex >= 0 && mainTypeIndex < shopLoader.primaryShop.mainTypes.Count)
|
||||
{
|
||||
var mainType = shopLoader.primaryShop.mainTypes[mainTypeIndex];
|
||||
if (subTypeIndex >= 0 && subTypeIndex < mainType.subTypes.Count)
|
||||
{
|
||||
return mainType.subTypes[subTypeIndex];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
void CreateItemPanelFromPool(GShopItem item, int targetSiblingIndex)
|
||||
{
|
||||
GameObject itemPanel = null;
|
||||
@@ -273,6 +441,8 @@ public class ShopUIManager : MonoBehaviour
|
||||
Debug.LogError("ShopDetailPanel script not found on shopDetailPanel GameObject!");
|
||||
// Fallback to the old method
|
||||
UpdateDetailPanel(item);
|
||||
detailScrollRect.verticalNormalizedPosition = 1f;
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(detailScrollRect.content);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,7 +471,7 @@ public class ShopUIManager : MonoBehaviour
|
||||
|
||||
if (detailItemPrice != null)
|
||||
detailItemPrice.text = $"Price: {bestPrice}";
|
||||
|
||||
Debug.Log($"Detail item price: {detailItemPrice.text}, detail item price != null: {detailItemPrice != null}");
|
||||
// Load icon based on item name (you'll need to implement icon loading)
|
||||
if (detailItemIcon != null)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace BrewMonster.Scripts.World
|
||||
protected A3DTerrain2 m_pA3DTerrain;
|
||||
CECOrnamentMan m_pOnmtMan;
|
||||
uint m_dwBornStamp = 0;
|
||||
int m_idInst = 161; // id of instance
|
||||
|
||||
public uint GetBornStamp() { return m_dwBornStamp++; }
|
||||
|
||||
@@ -26,5 +27,8 @@ namespace BrewMonster.Scripts.World
|
||||
{
|
||||
return m_pOnmtMan;
|
||||
}
|
||||
}
|
||||
|
||||
// Get id of instance
|
||||
public int GetInstanceID(){ return m_idInst; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
using BrewMonster.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster.Scripts
|
||||
{
|
||||
public class CECInstance
|
||||
{
|
||||
int m_id = 161; // Instance ID
|
||||
ushort[] m_strName; // Instance name
|
||||
string m_strPath; // Path
|
||||
int m_iRowNum = 3; // Number of map row
|
||||
int m_iColNum = 4; // Number of map column
|
||||
bool m_bLimitJump = false; // ÊÇ·ñÏÞÌø
|
||||
List<string> m_routeFiles;
|
||||
|
||||
public CECInstance()
|
||||
{
|
||||
m_id = 161;
|
||||
m_iRowNum = 3;
|
||||
m_iColNum = 4;
|
||||
m_bLimitJump = false;
|
||||
}
|
||||
|
||||
// Get instance ID
|
||||
public int GetID() { return m_id; }
|
||||
// Get instance name
|
||||
public ushort[] GetName() { return m_strName; }
|
||||
// Get instance data path
|
||||
public string GetPath() { return m_strPath; }
|
||||
// Get row and column number of map
|
||||
public int GetRowNum(){ return m_iRowNum; }
|
||||
public int GetColNum(){ return m_iColNum; }
|
||||
public bool GetLimitJump(){ return m_bLimitJump; }
|
||||
public List<string> GetRouteFiles(){ return m_routeFiles; }
|
||||
public bool GetPositionRelatedTexture(float x, float z, string filePath)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Load instance information from file
|
||||
public bool Load(AWScriptFile psf)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d943e5add12fde4dbb6e3bea3dc4d65
|
||||
@@ -896,7 +896,9 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
itemNameText: {fileID: 2676848775259769377}
|
||||
itemDescriptionText: {fileID: 1509498505529622136}
|
||||
itemDescriptionText:
|
||||
legacy: {fileID: 0}
|
||||
tmp: {fileID: 1509498505529622136}
|
||||
itemIconImage: {fileID: 5729739685989188916}
|
||||
itemPriceText: {fileID: 3533247489785110134}
|
||||
closeButton: {fileID: 0}
|
||||
|
||||
@@ -1899,7 +1899,7 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 21, y: -22.97}
|
||||
m_AnchoredPosition: {x: 21, y: -0}
|
||||
m_SizeDelta: {x: 472.5032, y: 0}
|
||||
m_Pivot: {x: 0, y: 0.5}
|
||||
--- !u!222 &2043307214318211948
|
||||
@@ -1930,7 +1930,7 @@ MonoBehaviour:
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text: aaa
|
||||
m_text:
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 369c2e14814cc9a4b8e3ad4e37769134, type: 2}
|
||||
m_sharedMaterial: {fileID: 9092487103257209053, guid: 369c2e14814cc9a4b8e3ad4e37769134, type: 2}
|
||||
@@ -4442,6 +4442,7 @@ RectTransform:
|
||||
m_Children:
|
||||
- {fileID: 9106031791145292554}
|
||||
- {fileID: 1001152567372181051}
|
||||
- {fileID: 1333165094145940333}
|
||||
m_Father: {fileID: 5834405183358786743}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
@@ -7163,6 +7164,157 @@ MonoBehaviour:
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!1 &5371522206622176611
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1333165094145940333}
|
||||
- component: {fileID: 7370426642012978972}
|
||||
- component: {fileID: 37862130938576806}
|
||||
- component: {fileID: 9183113038478938762}
|
||||
m_Layer: 5
|
||||
m_Name: Text (TMP) (2)
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1333165094145940333
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5371522206622176611}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7205431771786927886}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 21, y: -57.98}
|
||||
m_SizeDelta: {x: 465.7476, y: 0}
|
||||
m_Pivot: {x: 0, y: 0.5}
|
||||
--- !u!222 &7370426642012978972
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5371522206622176611}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &37862130938576806
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5371522206622176611}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text:
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 369c2e14814cc9a4b8e3ad4e37769134, type: 2}
|
||||
m_sharedMaterial: {fileID: 9092487103257209053, guid: 369c2e14814cc9a4b8e3ad4e37769134, type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_enableVertexGradient: 0
|
||||
m_colorMode: 3
|
||||
m_fontColorGradient:
|
||||
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_fontColorGradientPreset: {fileID: 0}
|
||||
m_spriteAsset: {fileID: 0}
|
||||
m_tintAllSprites: 0
|
||||
m_StyleSheet: {fileID: 0}
|
||||
m_TextStyleHashCode: -1183493901
|
||||
m_overrideHtmlColors: 0
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 36
|
||||
m_fontSizeBase: 36
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 0
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 72
|
||||
m_fontStyle: 0
|
||||
m_HorizontalAlignment: 1
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 0
|
||||
m_ActiveFontFeatures: 6e72656b
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 1
|
||||
m_isCullingEnabled: 0
|
||||
m_horizontalMapping: 0
|
||||
m_verticalMapping: 0
|
||||
m_uvLineOffset: 0
|
||||
m_geometrySortingOrder: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_VertexBufferAutoSizeReduction: 0
|
||||
m_useMaxVisibleDescender: 1
|
||||
m_pageToDisplay: 1
|
||||
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_isUsingLegacyAnimationComponent: 0
|
||||
m_isVolumetricText: 0
|
||||
m_hasFontAssetChanged: 0
|
||||
m_baseMaterial: {fileID: 0}
|
||||
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
|
||||
--- !u!114 &9183113038478938762
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5371522206622176611}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_HorizontalFit: 0
|
||||
m_VerticalFit: 2
|
||||
--- !u!1 &5460797107099608431
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -8046,13 +8198,13 @@ MonoBehaviour:
|
||||
hideDetailOnStart: 1
|
||||
nameText:
|
||||
legacy: {fileID: 0}
|
||||
tmp: {fileID: 7082730707602873357}
|
||||
tmp: {fileID: 0}
|
||||
descriptionText:
|
||||
legacy: {fileID: 0}
|
||||
tmp: {fileID: 6020258894941961325}
|
||||
extendedDescText:
|
||||
legacy: {fileID: 0}
|
||||
tmp: {fileID: 0}
|
||||
tmp: {fileID: 37862130938576806}
|
||||
equipButton: {fileID: 472698755110594484}
|
||||
dropButton: {fileID: 540159372834342487}
|
||||
autoRefresh: 1
|
||||
@@ -11506,7 +11658,7 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 21, y: -68.909996}
|
||||
m_AnchoredPosition: {x: 21, y: -28.989998}
|
||||
m_SizeDelta: {x: 465.7476, y: 0}
|
||||
m_Pivot: {x: 0, y: 0.5}
|
||||
--- !u!222 &5347950336050242333
|
||||
|
||||
+335
-1057
File diff suppressed because it is too large
Load Diff
@@ -1943,9 +1943,9 @@ RectTransform:
|
||||
- {fileID: 4504331075840543341}
|
||||
m_Father: {fileID: 1361524257611413148}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 108.9562, y: -31.05}
|
||||
m_SizeDelta: {x: 179.9124, y: 68.0217}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &8804506040386004496
|
||||
@@ -5768,9 +5768,9 @@ RectTransform:
|
||||
- {fileID: 2027606699309904338}
|
||||
m_Father: {fileID: 1361524257611413148}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 468.781, y: -31.05}
|
||||
m_SizeDelta: {x: 179.9124, y: 68.0217}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6741821173640675138
|
||||
@@ -18122,9 +18122,9 @@ RectTransform:
|
||||
- {fileID: 911293677621153352}
|
||||
m_Father: {fileID: 1361524257611413148}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 288.8686, y: -31.05}
|
||||
m_SizeDelta: {x: 179.9124, y: 68.0217}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5623009994815814977
|
||||
|
||||
@@ -597,7 +597,7 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: -25.6, y: -19.5}
|
||||
m_AnchoredPosition: {x: -25, y: -20}
|
||||
m_SizeDelta: {x: 36, y: 24}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6137065207749229268
|
||||
@@ -676,7 +676,7 @@ RectTransform:
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 38.34253, y: -20.45288}
|
||||
m_SizeDelta: {x: -87.68497, y: -48.1007}
|
||||
m_SizeDelta: {x: -87.68497, y: -48.1009}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3282283742538992330
|
||||
CanvasRenderer:
|
||||
@@ -760,7 +760,7 @@ GameObject:
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
m_IsActive: 0
|
||||
--- !u!224 &6862529442018877370
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -768,7 +768,7 @@ RectTransform:
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5207380909195611422}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
@@ -778,8 +778,8 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 256.80002, y: -17.547}
|
||||
m_SizeDelta: {x: 47.24, y: 35.094}
|
||||
m_AnchoredPosition: {x: 267.715, y: -17.547}
|
||||
m_SizeDelta: {x: 25.41, y: 35.094}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &9094358577136577940
|
||||
CanvasRenderer:
|
||||
@@ -809,7 +809,7 @@ MonoBehaviour:
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text: 1000
|
||||
m_text: 24
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 369c2e14814cc9a4b8e3ad4e37769134, type: 2}
|
||||
m_sharedMaterial: {fileID: 9092487103257209053, guid: 369c2e14814cc9a4b8e3ad4e37769134, type: 2}
|
||||
@@ -928,7 +928,7 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: -24.4, y: -19.5}
|
||||
m_AnchoredPosition: {x: -25, y: -19.5}
|
||||
m_SizeDelta: {x: 36, y: 24}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &8769089508493293562
|
||||
@@ -1073,7 +1073,7 @@ RectTransform:
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8378347976037059457}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
@@ -1083,9 +1083,9 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 169.03502, y: -17.547}
|
||||
m_SizeDelta: {x: 8.29, y: 35.094}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 280.42, y: -17.547}
|
||||
m_SizeDelta: {x: 59.66, y: 35.094}
|
||||
m_Pivot: {x: 1, y: 0.5}
|
||||
--- !u!222 &1217550950535449853
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -1114,7 +1114,7 @@ MonoBehaviour:
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text: 1
|
||||
m_text: 10204
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: 369c2e14814cc9a4b8e3ad4e37769134, type: 2}
|
||||
m_sharedMaterial: {fileID: 9092487103257209053, guid: 369c2e14814cc9a4b8e3ad4e37769134, type: 2}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:94045fc7eb49643c229531f88aa7ac1d8a6f59d3e0d2bfb5a4939f9b3fb0ed04
|
||||
size 200173095
|
||||
oid sha256:8003b60a4af29a6f7767b8b3f782a1f7fd576ce667bdbcfd0124f3071e3e5c0d
|
||||
size 200174193
|
||||
|
||||
@@ -5,6 +5,7 @@ using CSNetwork;
|
||||
using CSNetwork.GPDataType;
|
||||
using CSNetwork.GPDataType;
|
||||
using CSNetwork.Protocols.RPCData;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Threading.Tasks;
|
||||
using Unity.Cinemachine;
|
||||
@@ -27,6 +28,7 @@ public partial class CECGameRun
|
||||
|
||||
public CECWorld GetWorld() { return m_pWorld; }
|
||||
|
||||
private static Dictionary<int, CECInstance> m_InstTab = new Dictionary<int, CECInstance>();
|
||||
public void Init()
|
||||
{
|
||||
Application.targetFrameRate = 60;
|
||||
@@ -40,6 +42,13 @@ public partial class CECGameRun
|
||||
// LoadPrefabs();
|
||||
EC_ManMessage.RegisterHandler(this);
|
||||
|
||||
// Load instance information
|
||||
//if (!LoadInstanceInfo("Configs\\instance.txt"))
|
||||
//{
|
||||
// glb_ErrorOutput(ECERR_FAILEDTOCALL, "CECGameRun::Init", __LINE__);
|
||||
// return false;
|
||||
//}
|
||||
m_InstTab.Add(161, new CECInstance());
|
||||
AddressableManager.Instance.OnDispose += Dispose;
|
||||
}
|
||||
|
||||
@@ -317,4 +326,15 @@ public partial class CECGameRun
|
||||
}
|
||||
return m_pUIManager;
|
||||
}
|
||||
|
||||
|
||||
// Get instance by ID
|
||||
public CECInstance GetInstance(int id)
|
||||
{
|
||||
if (m_InstTab.TryGetValue(id, out CECInstance value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,35 +54,74 @@ namespace BrewMonster
|
||||
|
||||
protected bool LoadANSIStrings(string resourceName)
|
||||
{
|
||||
TextAsset textAsset = Resources.Load<TextAsset>(resourceName);
|
||||
if (textAsset == null)
|
||||
try
|
||||
{
|
||||
Debug.LogError($"[CECStringTab] Resource not found: {resourceName}");
|
||||
// If a real file path is provided (e.g. StreamingAssets), read directly from disk.
|
||||
// 如果提供的是实际文件路径(例如 StreamingAssets),则直接从磁盘读取。
|
||||
if (File.Exists(resourceName))
|
||||
{
|
||||
// ANSI tables are in CP936 in original PW; keep using CP936 decoder.
|
||||
// 原版完美世界的ANSI表是CP936编码,这里保持一致。
|
||||
byte[] bytes = File.ReadAllBytes(resourceName);
|
||||
string content = ByteToStringUtils.ByteArrayToCP936String(bytes);
|
||||
using var srFile = new StringReader(content);
|
||||
return ParseIntoDict(srFile, isWide: false);
|
||||
}
|
||||
|
||||
// Fallback to Resources (old behaviour).
|
||||
// 回退到 Resources 加载(旧行为)。
|
||||
TextAsset textAsset = Resources.Load<TextAsset>(resourceName);
|
||||
if (textAsset == null)
|
||||
{
|
||||
Debug.LogError($"[CECStringTab] Resource not found: {resourceName}");
|
||||
return false;
|
||||
}
|
||||
|
||||
string resContent = ByteToStringUtils.ByteArrayToCP936String(textAsset.bytes);
|
||||
using var srRes = new StringReader(resContent);
|
||||
return ParseIntoDict(srRes, isWide: false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[CECStringTab] LoadANSIStrings failed for '{resourceName}': {e}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Giải mã bytes -> string (ANSI: dùng Encoding.Default)
|
||||
string content = ByteToStringUtils.ByteArrayToCP936String(textAsset.bytes);
|
||||
using var sr = new StringReader(content);
|
||||
return ParseIntoDict(sr, isWide: false);
|
||||
}
|
||||
|
||||
protected bool LoadWideStrings(string resourceName)
|
||||
{
|
||||
TextAsset textAsset = Resources.Load<TextAsset>(resourceName);
|
||||
if (textAsset == null)
|
||||
try
|
||||
{
|
||||
Debug.LogError($"[CECStringTab] Resource not found: {resourceName}");
|
||||
// Support absolute / relative filesystem paths (e.g. StreamingAssets/configs/*.txt)
|
||||
// 支持文件系统路径(例如 StreamingAssets/configs/*.txt)
|
||||
if (File.Exists(resourceName))
|
||||
{
|
||||
// String tables we ship in StreamingAssets are saved as UTF-8.
|
||||
// 我们放在 StreamingAssets 里的字符串表保存为 UTF-8。
|
||||
string content = File.ReadAllText(resourceName, Encoding.UTF8);
|
||||
using var srFile = new StringReader(content);
|
||||
return ParseIntoDict(srFile, isWide: true);
|
||||
}
|
||||
|
||||
// Fallback to Resources-based loading (old behaviour)
|
||||
// 回退到基于 Resources 的加载(旧行为)
|
||||
TextAsset textAsset = Resources.Load<TextAsset>(resourceName);
|
||||
if (textAsset == null)
|
||||
{
|
||||
Debug.LogError($"[CECStringTab] Resource not found: {resourceName}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unity TextAsset.text is already UTF-8 decoded.
|
||||
string resContent = textAsset.text;
|
||||
using var srRes = new StringReader(resContent);
|
||||
return ParseIntoDict(srRes, isWide: true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"[CECStringTab] LoadWideStrings failed for '{resourceName}': {e}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unity TextAsset mặc định đã decode text UTF8 -> textAsset.text
|
||||
// nhưng để chắc chắn BOM/Unicode thì đọc từ bytes
|
||||
string content;
|
||||
content = textAsset.text;
|
||||
|
||||
using var sr = new StringReader(content);
|
||||
return ParseIntoDict(sr, isWide: true);
|
||||
}
|
||||
|
||||
private static Encoding DetectEncoding(byte[] bom)
|
||||
@@ -183,6 +222,18 @@ namespace BrewMonster
|
||||
|
||||
private void PutString(int id, string value, bool isWide)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return;
|
||||
|
||||
// Many PW string tables wrap the payload in double quotes, e.g.:
|
||||
// 12345 "^ffcb4aSome text\rMore text"
|
||||
// Strip a single leading/trailing quote pair to avoid showing raw quotes in UI.
|
||||
// 许多字符串表会用双引号包裹内容,这里去掉首尾各一个引号以避免在UI中显示多余的引号。
|
||||
if (value.Length >= 2 && value[0] == '"' && value[value.Length - 1] == '"')
|
||||
{
|
||||
value = value.Substring(1, value.Length - 2);
|
||||
}
|
||||
|
||||
if (isWide) m_WStrTab[id] = value;
|
||||
else m_AStrTab[id] = value;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user