Compare commits
2 Commits
issue-9-sa
...
claude/mak
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5d046c91a | ||
|
|
c2804fe1a6 |
524
assets/Effect/ymir work/effect/background/moonlight_eff_bat.mse
Normal file
524
assets/Effect/ymir work/effect/background/moonlight_eff_bat.mse
Normal file
@@ -0,0 +1,524 @@
|
|||||||
|
BoundingSphereRadius 0.000000
|
||||||
|
BoundingSpherePosition 0.000000 0.000000 0.000000
|
||||||
|
|
||||||
|
Group Particle
|
||||||
|
{
|
||||||
|
StartTime 0.176000
|
||||||
|
List TimeEventPosition
|
||||||
|
{
|
||||||
|
0.000000 "MOVING_TYPE_DIRECT" 0.000000 0.000000 0.000000
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticRotation 0.000000 0.000000 0.000000
|
||||||
|
Group EmitterProperty
|
||||||
|
{
|
||||||
|
MaxEmissionCount 1
|
||||||
|
|
||||||
|
CycleLength 10.000000
|
||||||
|
CycleLoopEnable 1
|
||||||
|
LoopCount 3
|
||||||
|
|
||||||
|
EmitterShape 0
|
||||||
|
EmitterAdvancedType 0
|
||||||
|
EmitterEmitFromEdgeFlag 0
|
||||||
|
EmittingDirection 0.080000 0.000000 0.000000
|
||||||
|
|
||||||
|
List TimeEventEmittingSize
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingAngularVelocity
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionX
|
||||||
|
{
|
||||||
|
0.000000 5.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionY
|
||||||
|
{
|
||||||
|
0.000000 -50.000000
|
||||||
|
0.100000 -20.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionZ
|
||||||
|
{
|
||||||
|
0.000000 10.000000
|
||||||
|
0.050000 100.000000
|
||||||
|
0.100000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingVelocity
|
||||||
|
{
|
||||||
|
0.000000 15.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmissionCountPerSecond
|
||||||
|
{
|
||||||
|
0.000000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventLifeTime
|
||||||
|
{
|
||||||
|
0.000000 10.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeX
|
||||||
|
{
|
||||||
|
0.000000 60.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeY
|
||||||
|
{
|
||||||
|
0.000000 36.000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Group ParticleProperty
|
||||||
|
{
|
||||||
|
SrcBlendType 5
|
||||||
|
DestBlendType 6
|
||||||
|
ColorOperationType 4
|
||||||
|
BillboardType 1
|
||||||
|
RotationType 0
|
||||||
|
RotationSpeed 0.000000
|
||||||
|
RotationRandomStartingBegin 0
|
||||||
|
RotationRandomStartingEnd 0
|
||||||
|
|
||||||
|
AttachEnable 1
|
||||||
|
StretchEnable 0
|
||||||
|
|
||||||
|
TexAniType 1
|
||||||
|
TexAniDelay 0.040000
|
||||||
|
TexAniRandomStartFrameEnable 0
|
||||||
|
EnableFrustum 0
|
||||||
|
|
||||||
|
List TimeEventGravity
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventAirResistance
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventScaleX
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventScaleY
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorRed
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorGreen
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorBlue
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventAlpha
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
0.737143 1.000000
|
||||||
|
1.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventRotation
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TextureFiles
|
||||||
|
{
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_01.dds"
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_02.dds"
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_03.dds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Group Particle
|
||||||
|
{
|
||||||
|
StartTime 0.072000
|
||||||
|
List TimeEventPosition
|
||||||
|
{
|
||||||
|
0.000000 "MOVING_TYPE_DIRECT" 0.000000 0.000000 0.000000
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticRotation 0.000000 0.000000 0.000000
|
||||||
|
Group EmitterProperty
|
||||||
|
{
|
||||||
|
MaxEmissionCount 1
|
||||||
|
|
||||||
|
CycleLength 10.000000
|
||||||
|
CycleLoopEnable 1
|
||||||
|
LoopCount 3
|
||||||
|
|
||||||
|
EmitterShape 0
|
||||||
|
EmitterAdvancedType 0
|
||||||
|
EmitterEmitFromEdgeFlag 0
|
||||||
|
EmittingDirection 0.080000 0.000000 0.000000
|
||||||
|
|
||||||
|
List TimeEventEmittingSize
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingAngularVelocity
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionX
|
||||||
|
{
|
||||||
|
0.000000 15.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionY
|
||||||
|
{
|
||||||
|
0.000000 -50.000000
|
||||||
|
0.100000 -20.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionZ
|
||||||
|
{
|
||||||
|
0.000000 10.000000
|
||||||
|
0.050000 50.000000
|
||||||
|
0.100000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingVelocity
|
||||||
|
{
|
||||||
|
0.000000 15.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmissionCountPerSecond
|
||||||
|
{
|
||||||
|
0.000000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventLifeTime
|
||||||
|
{
|
||||||
|
0.000000 10.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeX
|
||||||
|
{
|
||||||
|
0.000000 72.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeY
|
||||||
|
{
|
||||||
|
0.000000 48.000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Group ParticleProperty
|
||||||
|
{
|
||||||
|
SrcBlendType 5
|
||||||
|
DestBlendType 6
|
||||||
|
ColorOperationType 4
|
||||||
|
BillboardType 1
|
||||||
|
RotationType 0
|
||||||
|
RotationSpeed 0.000000
|
||||||
|
RotationRandomStartingBegin 0
|
||||||
|
RotationRandomStartingEnd 0
|
||||||
|
|
||||||
|
AttachEnable 1
|
||||||
|
StretchEnable 0
|
||||||
|
|
||||||
|
TexAniType 1
|
||||||
|
TexAniDelay 0.040000
|
||||||
|
TexAniRandomStartFrameEnable 0
|
||||||
|
EnableFrustum 0
|
||||||
|
|
||||||
|
List TimeEventGravity
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventAirResistance
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventScaleX
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventScaleY
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorRed
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorGreen
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorBlue
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventAlpha
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
0.737143 1.000000
|
||||||
|
1.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventRotation
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TextureFiles
|
||||||
|
{
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_01.dds"
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_02.dds"
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_03.dds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Group Particle
|
||||||
|
{
|
||||||
|
StartTime 0.000000
|
||||||
|
List TimeEventPosition
|
||||||
|
{
|
||||||
|
0.000000 "MOVING_TYPE_DIRECT" 0.000000 0.000000 0.000000
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticRotation 0.000000 0.000000 0.000000
|
||||||
|
Group EmitterProperty
|
||||||
|
{
|
||||||
|
MaxEmissionCount 1
|
||||||
|
|
||||||
|
CycleLength 10.000000
|
||||||
|
CycleLoopEnable 1
|
||||||
|
LoopCount 3
|
||||||
|
|
||||||
|
EmitterShape 0
|
||||||
|
EmitterAdvancedType 0
|
||||||
|
EmitterEmitFromEdgeFlag 0
|
||||||
|
EmittingDirection 0.080000 0.000000 0.000000
|
||||||
|
|
||||||
|
List TimeEventEmittingSize
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingAngularVelocity
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionX
|
||||||
|
{
|
||||||
|
0.000000 50.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionY
|
||||||
|
{
|
||||||
|
0.000000 -50.000000
|
||||||
|
0.100000 -20.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionZ
|
||||||
|
{
|
||||||
|
0.000000 10.000000
|
||||||
|
0.050000 100.000000
|
||||||
|
0.100000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingVelocity
|
||||||
|
{
|
||||||
|
0.000000 5.000000
|
||||||
|
0.083429 15.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmissionCountPerSecond
|
||||||
|
{
|
||||||
|
0.000000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventLifeTime
|
||||||
|
{
|
||||||
|
0.000000 10.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeX
|
||||||
|
{
|
||||||
|
0.000000 60.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeY
|
||||||
|
{
|
||||||
|
0.000000 36.000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Group ParticleProperty
|
||||||
|
{
|
||||||
|
SrcBlendType 5
|
||||||
|
DestBlendType 6
|
||||||
|
ColorOperationType 4
|
||||||
|
BillboardType 1
|
||||||
|
RotationType 0
|
||||||
|
RotationSpeed 0.000000
|
||||||
|
RotationRandomStartingBegin 0
|
||||||
|
RotationRandomStartingEnd 0
|
||||||
|
|
||||||
|
AttachEnable 1
|
||||||
|
StretchEnable 0
|
||||||
|
|
||||||
|
TexAniType 1
|
||||||
|
TexAniDelay 0.040000
|
||||||
|
TexAniRandomStartFrameEnable 0
|
||||||
|
EnableFrustum 0
|
||||||
|
|
||||||
|
List TimeEventGravity
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventAirResistance
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventScaleX
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventScaleY
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorRed
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorGreen
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorBlue
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventAlpha
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
0.737143 1.000000
|
||||||
|
1.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventRotation
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TextureFiles
|
||||||
|
{
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_01.dds"
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_02.dds"
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_03.dds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Group Particle
|
||||||
|
{
|
||||||
|
StartTime 0.000000
|
||||||
|
List TimeEventPosition
|
||||||
|
{
|
||||||
|
0.000000 "MOVING_TYPE_DIRECT" 0.000000 0.000000 0.000000
|
||||||
|
0.216000 "MOVING_TYPE_DIRECT" 0.000000 -20.000000 20.000000
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticRotation 0.000000 0.000000 0.000000
|
||||||
|
Group EmitterProperty
|
||||||
|
{
|
||||||
|
MaxEmissionCount 30
|
||||||
|
|
||||||
|
CycleLength 10.000000
|
||||||
|
CycleLoopEnable 1
|
||||||
|
LoopCount 3
|
||||||
|
|
||||||
|
EmitterShape 3
|
||||||
|
EmitterAdvancedType 1
|
||||||
|
EmittingRadius 80.000000
|
||||||
|
EmitterEmitFromEdgeFlag 0
|
||||||
|
EmittingDirection 0.010000 0.010000 0.010000
|
||||||
|
|
||||||
|
List TimeEventEmittingSize
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingAngularVelocity
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionX
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionY
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionZ
|
||||||
|
{
|
||||||
|
0.000000 20.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingVelocity
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmissionCountPerSecond
|
||||||
|
{
|
||||||
|
0.000000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventLifeTime
|
||||||
|
{
|
||||||
|
0.000000 10.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeX
|
||||||
|
{
|
||||||
|
0.000000 128.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeY
|
||||||
|
{
|
||||||
|
0.000000 128.000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Group ParticleProperty
|
||||||
|
{
|
||||||
|
SrcBlendType 5
|
||||||
|
DestBlendType 6
|
||||||
|
ColorOperationType 4
|
||||||
|
BillboardType 1
|
||||||
|
RotationType 4
|
||||||
|
RotationSpeed 56.000000
|
||||||
|
RotationRandomStartingBegin 360
|
||||||
|
RotationRandomStartingEnd 0
|
||||||
|
|
||||||
|
AttachEnable 0
|
||||||
|
StretchEnable 0
|
||||||
|
|
||||||
|
TexAniType 0
|
||||||
|
TexAniDelay 0.040000
|
||||||
|
TexAniRandomStartFrameEnable 0
|
||||||
|
EnableFrustum 0
|
||||||
|
|
||||||
|
List TimeEventGravity
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventAirResistance
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
0.034286 0.100000
|
||||||
|
}
|
||||||
|
List TimeEventScaleX
|
||||||
|
{
|
||||||
|
0.000000 0.500000
|
||||||
|
1.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventScaleY
|
||||||
|
{
|
||||||
|
0.000000 0.500000
|
||||||
|
1.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorRed
|
||||||
|
{
|
||||||
|
0.000000 0.819608
|
||||||
|
}
|
||||||
|
List TimeEventColorGreen
|
||||||
|
{
|
||||||
|
0.000000 0.780392
|
||||||
|
}
|
||||||
|
List TimeEventColorBlue
|
||||||
|
{
|
||||||
|
0.000000 0.682353
|
||||||
|
}
|
||||||
|
List TimeEventAlpha
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
0.112821 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventRotation
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TextureFiles
|
||||||
|
{
|
||||||
|
"D:\Ymir Work\effect\monster2\smoke_dirt1.dds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,654 @@
|
|||||||
|
BoundingSphereRadius 0.000000
|
||||||
|
BoundingSpherePosition 0.000000 0.000000 0.000000
|
||||||
|
|
||||||
|
Group Particle
|
||||||
|
{
|
||||||
|
StartTime 0.176000
|
||||||
|
List TimeEventPosition
|
||||||
|
{
|
||||||
|
0.000000 "MOVING_TYPE_DIRECT" 0.000000 0.000000 0.000000
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticRotation 0.000000 0.000000 0.000000
|
||||||
|
Group EmitterProperty
|
||||||
|
{
|
||||||
|
MaxEmissionCount 1
|
||||||
|
|
||||||
|
CycleLength 20.000000
|
||||||
|
CycleLoopEnable 1
|
||||||
|
LoopCount 2
|
||||||
|
|
||||||
|
EmitterShape 0
|
||||||
|
EmitterAdvancedType 0
|
||||||
|
EmitterEmitFromEdgeFlag 0
|
||||||
|
EmittingDirection 0.080000 0.000000 0.000000
|
||||||
|
|
||||||
|
List TimeEventEmittingSize
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingAngularVelocity
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionX
|
||||||
|
{
|
||||||
|
0.000000 5.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionY
|
||||||
|
{
|
||||||
|
0.000000 50.000000
|
||||||
|
0.100000 20.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionZ
|
||||||
|
{
|
||||||
|
0.000000 10.000000
|
||||||
|
0.050000 100.000000
|
||||||
|
0.100000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingVelocity
|
||||||
|
{
|
||||||
|
0.000000 15.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmissionCountPerSecond
|
||||||
|
{
|
||||||
|
0.000000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventLifeTime
|
||||||
|
{
|
||||||
|
0.000000 20.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeX
|
||||||
|
{
|
||||||
|
0.000000 60.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeY
|
||||||
|
{
|
||||||
|
0.000000 36.000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Group ParticleProperty
|
||||||
|
{
|
||||||
|
SrcBlendType 5
|
||||||
|
DestBlendType 6
|
||||||
|
ColorOperationType 4
|
||||||
|
BillboardType 1
|
||||||
|
RotationType 0
|
||||||
|
RotationSpeed 0.000000
|
||||||
|
RotationRandomStartingBegin 0
|
||||||
|
RotationRandomStartingEnd 0
|
||||||
|
|
||||||
|
AttachEnable 1
|
||||||
|
StretchEnable 0
|
||||||
|
|
||||||
|
TexAniType 1
|
||||||
|
TexAniDelay 0.040000
|
||||||
|
TexAniRandomStartFrameEnable 0
|
||||||
|
EnableFrustum 0
|
||||||
|
|
||||||
|
List TimeEventGravity
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventAirResistance
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventScaleX
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventScaleY
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorRed
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorGreen
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorBlue
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventAlpha
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
0.376923 1.000000
|
||||||
|
0.500000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventRotation
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TextureFiles
|
||||||
|
{
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_01.dds"
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_02.dds"
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_03.dds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Group Particle
|
||||||
|
{
|
||||||
|
StartTime 0.072000
|
||||||
|
List TimeEventPosition
|
||||||
|
{
|
||||||
|
0.000000 "MOVING_TYPE_DIRECT" 0.000000 0.000000 0.000000
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticRotation 0.000000 0.000000 0.000000
|
||||||
|
Group EmitterProperty
|
||||||
|
{
|
||||||
|
MaxEmissionCount 1
|
||||||
|
|
||||||
|
CycleLength 20.000000
|
||||||
|
CycleLoopEnable 1
|
||||||
|
LoopCount 2
|
||||||
|
|
||||||
|
EmitterShape 0
|
||||||
|
EmitterAdvancedType 0
|
||||||
|
EmitterEmitFromEdgeFlag 0
|
||||||
|
EmittingDirection 0.080000 0.000000 0.000000
|
||||||
|
|
||||||
|
List TimeEventEmittingSize
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingAngularVelocity
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionX
|
||||||
|
{
|
||||||
|
0.000000 15.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionY
|
||||||
|
{
|
||||||
|
0.000000 50.000000
|
||||||
|
0.100000 20.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionZ
|
||||||
|
{
|
||||||
|
0.000000 10.000000
|
||||||
|
0.050000 50.000000
|
||||||
|
0.100000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingVelocity
|
||||||
|
{
|
||||||
|
0.000000 15.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmissionCountPerSecond
|
||||||
|
{
|
||||||
|
0.000000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventLifeTime
|
||||||
|
{
|
||||||
|
0.000000 20.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeX
|
||||||
|
{
|
||||||
|
0.000000 72.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeY
|
||||||
|
{
|
||||||
|
0.000000 48.000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Group ParticleProperty
|
||||||
|
{
|
||||||
|
SrcBlendType 5
|
||||||
|
DestBlendType 6
|
||||||
|
ColorOperationType 4
|
||||||
|
BillboardType 1
|
||||||
|
RotationType 0
|
||||||
|
RotationSpeed 0.000000
|
||||||
|
RotationRandomStartingBegin 0
|
||||||
|
RotationRandomStartingEnd 0
|
||||||
|
|
||||||
|
AttachEnable 1
|
||||||
|
StretchEnable 0
|
||||||
|
|
||||||
|
TexAniType 1
|
||||||
|
TexAniDelay 0.040000
|
||||||
|
TexAniRandomStartFrameEnable 0
|
||||||
|
EnableFrustum 0
|
||||||
|
|
||||||
|
List TimeEventGravity
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventAirResistance
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventScaleX
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventScaleY
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorRed
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorGreen
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorBlue
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventAlpha
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
0.387179 1.000000
|
||||||
|
0.517949 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventRotation
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TextureFiles
|
||||||
|
{
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_01.dds"
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_02.dds"
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_03.dds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Group Particle
|
||||||
|
{
|
||||||
|
StartTime 0.072000
|
||||||
|
List TimeEventPosition
|
||||||
|
{
|
||||||
|
0.000000 "MOVING_TYPE_DIRECT" 0.000000 0.000000 0.000000
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticRotation 0.000000 0.000000 0.000000
|
||||||
|
Group EmitterProperty
|
||||||
|
{
|
||||||
|
MaxEmissionCount 1
|
||||||
|
|
||||||
|
CycleLength 20.000000
|
||||||
|
CycleLoopEnable 1
|
||||||
|
LoopCount 2
|
||||||
|
|
||||||
|
EmitterShape 0
|
||||||
|
EmitterAdvancedType 0
|
||||||
|
EmitterEmitFromEdgeFlag 0
|
||||||
|
EmittingDirection 0.080000 0.000000 0.000000
|
||||||
|
|
||||||
|
List TimeEventEmittingSize
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingAngularVelocity
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionX
|
||||||
|
{
|
||||||
|
0.000000 15.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionY
|
||||||
|
{
|
||||||
|
0.000000 50.000000
|
||||||
|
0.100000 20.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionZ
|
||||||
|
{
|
||||||
|
0.000000 10.000000
|
||||||
|
0.050000 50.000000
|
||||||
|
0.100000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingVelocity
|
||||||
|
{
|
||||||
|
0.000000 15.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmissionCountPerSecond
|
||||||
|
{
|
||||||
|
0.000000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventLifeTime
|
||||||
|
{
|
||||||
|
0.000000 20.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeX
|
||||||
|
{
|
||||||
|
0.000000 72.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeY
|
||||||
|
{
|
||||||
|
0.000000 48.000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Group ParticleProperty
|
||||||
|
{
|
||||||
|
SrcBlendType 5
|
||||||
|
DestBlendType 6
|
||||||
|
ColorOperationType 4
|
||||||
|
BillboardType 1
|
||||||
|
RotationType 0
|
||||||
|
RotationSpeed 0.000000
|
||||||
|
RotationRandomStartingBegin 0
|
||||||
|
RotationRandomStartingEnd 0
|
||||||
|
|
||||||
|
AttachEnable 1
|
||||||
|
StretchEnable 0
|
||||||
|
|
||||||
|
TexAniType 1
|
||||||
|
TexAniDelay 0.040000
|
||||||
|
TexAniRandomStartFrameEnable 0
|
||||||
|
EnableFrustum 0
|
||||||
|
|
||||||
|
List TimeEventGravity
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventAirResistance
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventScaleX
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventScaleY
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorRed
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorGreen
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorBlue
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventAlpha
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
0.405128 1.000000
|
||||||
|
0.505128 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventRotation
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TextureFiles
|
||||||
|
{
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_01.dds"
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_02.dds"
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_03.dds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Group Particle
|
||||||
|
{
|
||||||
|
StartTime 0.000000
|
||||||
|
List TimeEventPosition
|
||||||
|
{
|
||||||
|
0.000000 "MOVING_TYPE_DIRECT" 0.000000 0.000000 0.000000
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticRotation 0.000000 0.000000 0.000000
|
||||||
|
Group EmitterProperty
|
||||||
|
{
|
||||||
|
MaxEmissionCount 1
|
||||||
|
|
||||||
|
CycleLength 20.000000
|
||||||
|
CycleLoopEnable 1
|
||||||
|
LoopCount 2
|
||||||
|
|
||||||
|
EmitterShape 0
|
||||||
|
EmitterAdvancedType 0
|
||||||
|
EmitterEmitFromEdgeFlag 0
|
||||||
|
EmittingDirection 0.100000 0.000000 0.050000
|
||||||
|
|
||||||
|
List TimeEventEmittingSize
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingAngularVelocity
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionX
|
||||||
|
{
|
||||||
|
0.000000 50.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionY
|
||||||
|
{
|
||||||
|
0.000000 50.000000
|
||||||
|
0.100000 20.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionZ
|
||||||
|
{
|
||||||
|
0.000000 10.000000
|
||||||
|
0.050000 100.000000
|
||||||
|
0.100000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingVelocity
|
||||||
|
{
|
||||||
|
0.000000 5.000000
|
||||||
|
0.083429 15.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmissionCountPerSecond
|
||||||
|
{
|
||||||
|
0.000000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventLifeTime
|
||||||
|
{
|
||||||
|
0.000000 20.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeX
|
||||||
|
{
|
||||||
|
0.000000 60.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeY
|
||||||
|
{
|
||||||
|
0.000000 36.000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Group ParticleProperty
|
||||||
|
{
|
||||||
|
SrcBlendType 5
|
||||||
|
DestBlendType 6
|
||||||
|
ColorOperationType 4
|
||||||
|
BillboardType 1
|
||||||
|
RotationType 0
|
||||||
|
RotationSpeed 0.000000
|
||||||
|
RotationRandomStartingBegin 0
|
||||||
|
RotationRandomStartingEnd 0
|
||||||
|
|
||||||
|
AttachEnable 1
|
||||||
|
StretchEnable 0
|
||||||
|
|
||||||
|
TexAniType 1
|
||||||
|
TexAniDelay 0.040000
|
||||||
|
TexAniRandomStartFrameEnable 0
|
||||||
|
EnableFrustum 0
|
||||||
|
|
||||||
|
List TimeEventGravity
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventAirResistance
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventScaleX
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventScaleY
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorRed
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorGreen
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorBlue
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventAlpha
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
0.382051 1.000000
|
||||||
|
0.500000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventRotation
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TextureFiles
|
||||||
|
{
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_01.dds"
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_02.dds"
|
||||||
|
"D:\Ymir Work\effect\pet\halloween_2022_coffin_bat_03.dds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Group Particle
|
||||||
|
{
|
||||||
|
StartTime 0.000000
|
||||||
|
List TimeEventPosition
|
||||||
|
{
|
||||||
|
0.000000 "MOVING_TYPE_DIRECT" 0.000000 0.000000 0.000000
|
||||||
|
0.216000 "MOVING_TYPE_DIRECT" 0.000000 -20.000000 20.000000
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticRotation 0.000000 0.000000 0.000000
|
||||||
|
Group EmitterProperty
|
||||||
|
{
|
||||||
|
MaxEmissionCount 30
|
||||||
|
|
||||||
|
CycleLength 20.000000
|
||||||
|
CycleLoopEnable 1
|
||||||
|
LoopCount 2
|
||||||
|
|
||||||
|
EmitterShape 3
|
||||||
|
EmitterAdvancedType 1
|
||||||
|
EmittingRadius 80.000000
|
||||||
|
EmitterEmitFromEdgeFlag 0
|
||||||
|
EmittingDirection 0.010000 0.010000 0.010000
|
||||||
|
|
||||||
|
List TimeEventEmittingSize
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingAngularVelocity
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionX
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionY
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingDirectionZ
|
||||||
|
{
|
||||||
|
0.000000 20.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmittingVelocity
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventEmissionCountPerSecond
|
||||||
|
{
|
||||||
|
0.000000 1000.000000
|
||||||
|
}
|
||||||
|
List TimeEventLifeTime
|
||||||
|
{
|
||||||
|
0.000000 20.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeX
|
||||||
|
{
|
||||||
|
0.000000 128.000000
|
||||||
|
}
|
||||||
|
List TimeEventSizeY
|
||||||
|
{
|
||||||
|
0.000000 128.000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Group ParticleProperty
|
||||||
|
{
|
||||||
|
SrcBlendType 5
|
||||||
|
DestBlendType 6
|
||||||
|
ColorOperationType 4
|
||||||
|
BillboardType 1
|
||||||
|
RotationType 4
|
||||||
|
RotationSpeed 56.000000
|
||||||
|
RotationRandomStartingBegin 360
|
||||||
|
RotationRandomStartingEnd 0
|
||||||
|
|
||||||
|
AttachEnable 0
|
||||||
|
StretchEnable 0
|
||||||
|
|
||||||
|
TexAniType 0
|
||||||
|
TexAniDelay 0.040000
|
||||||
|
TexAniRandomStartFrameEnable 0
|
||||||
|
EnableFrustum 0
|
||||||
|
|
||||||
|
List TimeEventGravity
|
||||||
|
{
|
||||||
|
}
|
||||||
|
List TimeEventAirResistance
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
0.034286 0.100000
|
||||||
|
}
|
||||||
|
List TimeEventScaleX
|
||||||
|
{
|
||||||
|
0.000000 0.500000
|
||||||
|
1.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventScaleY
|
||||||
|
{
|
||||||
|
0.000000 0.500000
|
||||||
|
1.000000 1.000000
|
||||||
|
}
|
||||||
|
List TimeEventColorRed
|
||||||
|
{
|
||||||
|
0.000000 0.819608
|
||||||
|
}
|
||||||
|
List TimeEventColorGreen
|
||||||
|
{
|
||||||
|
0.000000 0.780392
|
||||||
|
}
|
||||||
|
List TimeEventColorBlue
|
||||||
|
{
|
||||||
|
0.000000 0.682353
|
||||||
|
}
|
||||||
|
List TimeEventAlpha
|
||||||
|
{
|
||||||
|
0.000000 1.000000
|
||||||
|
0.050000 0.000000
|
||||||
|
}
|
||||||
|
List TimeEventRotation
|
||||||
|
{
|
||||||
|
0.000000 0.000000
|
||||||
|
}
|
||||||
|
List TextureFiles
|
||||||
|
{
|
||||||
|
"D:\Ymir Work\effect\monster2\smoke_dirt1.dds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
assets/Effect/ymir work/effect/background/mushrooma_01.mse
Normal file
35
assets/Effect/ymir work/effect/background/mushrooma_01.mse
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
BoundingSphereRadius 400.000000
|
||||||
|
BoundingSpherePosition -180.000000 -60.000000 650.000000
|
||||||
|
|
||||||
|
Group Mesh
|
||||||
|
{
|
||||||
|
StartTime 0.000000
|
||||||
|
List TimeEventPosition
|
||||||
|
{
|
||||||
|
0.000000 "MOVING_TYPE_DIRECT" 0.000000 0.000000 0.000000
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshFileName "mushroomA_01.mde"
|
||||||
|
MeshAnimationLoopEnable 1
|
||||||
|
MeshAnimationLoopCount 0
|
||||||
|
MeshAnimationFrameDelay 0.020000
|
||||||
|
|
||||||
|
MeshElementCount 1
|
||||||
|
Group MeshElement00
|
||||||
|
{
|
||||||
|
BillboardType 0
|
||||||
|
BlendingEnable 1
|
||||||
|
BlendingSrcType 5
|
||||||
|
BlendingDestType 2
|
||||||
|
|
||||||
|
TextureAnimationLoopEnable 1
|
||||||
|
TextureAnimationFrameDelay 0.020000
|
||||||
|
TextureAnimationStartFrame 0
|
||||||
|
|
||||||
|
ColorOperationType 5
|
||||||
|
ColorFactor 0.168627 0.643137 0.360784 1.000000
|
||||||
|
List TimeEventAlpha
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
assets/Effect/ymir work/effect/background/mushrooma_03.mse
Normal file
35
assets/Effect/ymir work/effect/background/mushrooma_03.mse
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
BoundingSphereRadius 500.000000
|
||||||
|
BoundingSpherePosition 100.000000 0.000000 550.000000
|
||||||
|
|
||||||
|
Group Mesh
|
||||||
|
{
|
||||||
|
StartTime 0.000000
|
||||||
|
List TimeEventPosition
|
||||||
|
{
|
||||||
|
0.000000 "MOVING_TYPE_DIRECT" 0.000000 0.000000 0.000000
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshFileName "mushroomA_03.mde"
|
||||||
|
MeshAnimationLoopEnable 1
|
||||||
|
MeshAnimationLoopCount 0
|
||||||
|
MeshAnimationFrameDelay 0.020000
|
||||||
|
|
||||||
|
MeshElementCount 1
|
||||||
|
Group MeshElement00
|
||||||
|
{
|
||||||
|
BillboardType 0
|
||||||
|
BlendingEnable 1
|
||||||
|
BlendingSrcType 5
|
||||||
|
BlendingDestType 2
|
||||||
|
|
||||||
|
TextureAnimationLoopEnable 1
|
||||||
|
TextureAnimationFrameDelay 0.020000
|
||||||
|
TextureAnimationStartFrame 0
|
||||||
|
|
||||||
|
ColorOperationType 5
|
||||||
|
ColorFactor 0.184314 0.643137 0.462745 1.000000
|
||||||
|
List TimeEventAlpha
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
assets/Effect/ymir work/effect/background/mushrooma_04.mse
Normal file
35
assets/Effect/ymir work/effect/background/mushrooma_04.mse
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
BoundingSphereRadius 330.000000
|
||||||
|
BoundingSpherePosition -160.000000 0.000000 370.000000
|
||||||
|
|
||||||
|
Group Mesh
|
||||||
|
{
|
||||||
|
StartTime 0.000000
|
||||||
|
List TimeEventPosition
|
||||||
|
{
|
||||||
|
0.000000 "MOVING_TYPE_DIRECT" 0.000000 0.000000 0.000000
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshFileName "mushroomA_04.mde"
|
||||||
|
MeshAnimationLoopEnable 1
|
||||||
|
MeshAnimationLoopCount 0
|
||||||
|
MeshAnimationFrameDelay 0.020000
|
||||||
|
|
||||||
|
MeshElementCount 1
|
||||||
|
Group MeshElement00
|
||||||
|
{
|
||||||
|
BillboardType 0
|
||||||
|
BlendingEnable 1
|
||||||
|
BlendingSrcType 5
|
||||||
|
BlendingDestType 2
|
||||||
|
|
||||||
|
TextureAnimationLoopEnable 1
|
||||||
|
TextureAnimationFrameDelay 0.020000
|
||||||
|
TextureAnimationStartFrame 0
|
||||||
|
|
||||||
|
ColorOperationType 5
|
||||||
|
ColorFactor 0.200000 0.521569 0.227451 1.000000
|
||||||
|
List TimeEventAlpha
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
BoundingSphereRadius 2500.000000
|
||||||
|
BoundingSpherePosition 0.000000 0.000000 1800.000000
|
||||||
|
|
||||||
|
Group Mesh
|
||||||
|
{
|
||||||
|
StartTime 0.000000
|
||||||
|
List TimeEventPosition
|
||||||
|
{
|
||||||
|
0.000000 "MOVING_TYPE_DIRECT" 0.000000 0.000000 0.000000
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshFileName "turtle_statue_tree_roof_light01.mde"
|
||||||
|
MeshAnimationLoopEnable 1
|
||||||
|
MeshAnimationLoopCount 0
|
||||||
|
MeshAnimationFrameDelay 0.020000
|
||||||
|
|
||||||
|
MeshElementCount 1
|
||||||
|
Group MeshElement00
|
||||||
|
{
|
||||||
|
BillboardType 0
|
||||||
|
BlendingEnable 1
|
||||||
|
BlendingSrcType 5
|
||||||
|
BlendingDestType 2
|
||||||
|
|
||||||
|
TextureAnimationLoopEnable 1
|
||||||
|
TextureAnimationFrameDelay 0.020000
|
||||||
|
TextureAnimationStartFrame 0
|
||||||
|
|
||||||
|
ColorOperationType 5
|
||||||
|
ColorFactor 0.772549 0.733333 0.188235 1.000000
|
||||||
|
List TimeEventAlpha
|
||||||
|
{
|
||||||
|
0.046667 0.577320
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,5 @@
|
|||||||
ScriptType MotionData
|
ScriptType MotionData
|
||||||
|
|
||||||
MotionFileName "D:\Ymir Work\monster\orc_lord\30_1.GR2"
|
MotionFileName "D:\Ymir Work\monster\orc_lord\32_1.GR2"
|
||||||
MotionDuration 0.833333
|
MotionDuration 0.833333
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -33,9 +33,6 @@ import uiAffectShower
|
|||||||
import uiPlayerGauge
|
import uiPlayerGauge
|
||||||
import uiCharacter
|
import uiCharacter
|
||||||
import uiTarget
|
import uiTarget
|
||||||
import uiAutopickup
|
|
||||||
import uiStoneQueue
|
|
||||||
import uiSwitchbot
|
|
||||||
|
|
||||||
# PRIVATE_SHOP_PRICE_LIST
|
# PRIVATE_SHOP_PRICE_LIST
|
||||||
import uiPrivateShopBuilder
|
import uiPrivateShopBuilder
|
||||||
@@ -58,157 +55,6 @@ from _weakref import proxy
|
|||||||
SCREENSHOT_CWDSAVE = False
|
SCREENSHOT_CWDSAVE = False
|
||||||
SCREENSHOT_DIR = None
|
SCREENSHOT_DIR = None
|
||||||
|
|
||||||
|
|
||||||
def _WriteHeadlessMapTrace(message):
|
|
||||||
if os.environ.get("M2_HEADLESS_SCENARIO", "").strip().lower() != "map_load":
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
open("log/headless_map_load_trace.txt", "a").write("%s\n" % message)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def _GetHeadlessScenario():
|
|
||||||
return os.environ.get("M2_HEADLESS_SCENARIO", "").strip().lower()
|
|
||||||
|
|
||||||
|
|
||||||
def _WriteHeadlessTrace(message):
|
|
||||||
scenario = _GetHeadlessScenario()
|
|
||||||
if scenario == "map_load":
|
|
||||||
tracePath = "log/headless_map_load_trace.txt"
|
|
||||||
elif scenario == "gm_teleport":
|
|
||||||
tracePath = "log/headless_gm_teleport_trace.txt"
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
open(tracePath, "a").write("%s\n" % message)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def _GetHeadlessFloat(name, default):
|
|
||||||
try:
|
|
||||||
return float(os.environ.get(name, str(default)))
|
|
||||||
except (TypeError, ValueError):
|
|
||||||
return default
|
|
||||||
|
|
||||||
|
|
||||||
def _GetHeadlessWarpSteps():
|
|
||||||
rawValue = os.environ.get("M2_HEADLESS_WARP_STEPS", "").strip()
|
|
||||||
steps = []
|
|
||||||
|
|
||||||
if not rawValue:
|
|
||||||
return steps
|
|
||||||
|
|
||||||
for rawStep in rawValue.split("|"):
|
|
||||||
rawStep = rawStep.strip()
|
|
||||||
if not rawStep:
|
|
||||||
continue
|
|
||||||
|
|
||||||
parts = [part.strip() for part in rawStep.split(",")]
|
|
||||||
if len(parts) != 3:
|
|
||||||
_WriteHeadlessTrace("Invalid warp step=%s" % rawStep)
|
|
||||||
continue
|
|
||||||
|
|
||||||
mapName = parts[0]
|
|
||||||
|
|
||||||
try:
|
|
||||||
globalX = int(parts[1])
|
|
||||||
globalY = int(parts[2])
|
|
||||||
except:
|
|
||||||
_WriteHeadlessTrace("Invalid warp coords step=%s" % rawStep)
|
|
||||||
continue
|
|
||||||
|
|
||||||
steps.append({
|
|
||||||
"map_name": mapName,
|
|
||||||
"global_x": globalX,
|
|
||||||
"global_y": globalY,
|
|
||||||
})
|
|
||||||
|
|
||||||
return steps
|
|
||||||
|
|
||||||
|
|
||||||
HEADLESS_GM_STATE = {
|
|
||||||
"initialized": False,
|
|
||||||
"steps": [],
|
|
||||||
"index": 0,
|
|
||||||
"phase": "idle",
|
|
||||||
"command_at": 0.0,
|
|
||||||
"deadline": 0.0,
|
|
||||||
"quit_requested": False,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _HeadlessGMEnabled():
|
|
||||||
return _GetHeadlessScenario() == "gm_teleport"
|
|
||||||
|
|
||||||
|
|
||||||
def _HeadlessGMCommandDelay():
|
|
||||||
return _GetHeadlessFloat("M2_HEADLESS_COMMAND_DELAY", 5.0)
|
|
||||||
|
|
||||||
|
|
||||||
def _HeadlessGMWarpTimeout():
|
|
||||||
return _GetHeadlessFloat("M2_HEADLESS_WARP_TIMEOUT", 20.0)
|
|
||||||
|
|
||||||
|
|
||||||
def _HeadlessGMSettleDelay():
|
|
||||||
return _GetHeadlessFloat("M2_HEADLESS_SETTLE_DELAY", 2.0)
|
|
||||||
|
|
||||||
|
|
||||||
def _HeadlessGMRequestQuit(message):
|
|
||||||
global HEADLESS_GM_STATE
|
|
||||||
|
|
||||||
if message:
|
|
||||||
_WriteHeadlessTrace(message)
|
|
||||||
|
|
||||||
if HEADLESS_GM_STATE.get("quit_requested"):
|
|
||||||
return
|
|
||||||
|
|
||||||
HEADLESS_GM_STATE["quit_requested"] = True
|
|
||||||
app.Exit()
|
|
||||||
|
|
||||||
|
|
||||||
class _HeadlessDummy(object):
|
|
||||||
def __call__(self, *args, **kwargs):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __nonzero__(self):
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
_HEADLESS_DUMMY = _HeadlessDummy()
|
|
||||||
|
|
||||||
|
|
||||||
class _HeadlessInterface(object):
|
|
||||||
def MakeInterface(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def ShowDefaultWindows(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def HideAllWindows(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def Close(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def BUILD_OnUpdate(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def OpenWhisperDialog(self, *args):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def SetMapName(self, *args):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
|
||||||
return _HEADLESS_DUMMY
|
|
||||||
|
|
||||||
cameraDistance = 1550.0
|
cameraDistance = 1550.0
|
||||||
cameraPitch = 27.0
|
cameraPitch = 27.0
|
||||||
cameraRotation = 0.0
|
cameraRotation = 0.0
|
||||||
@@ -218,7 +64,6 @@ testAlignment = 0
|
|||||||
|
|
||||||
class GameWindow(ui.ScriptWindow):
|
class GameWindow(ui.ScriptWindow):
|
||||||
def __init__(self, stream):
|
def __init__(self, stream):
|
||||||
_WriteHeadlessTrace("GameWindow.__init__ begin")
|
|
||||||
ui.ScriptWindow.__init__(self, "GAME")
|
ui.ScriptWindow.__init__(self, "GAME")
|
||||||
self.SetWindowName("game")
|
self.SetWindowName("game")
|
||||||
net.SetPhaseWindow(net.PHASE_WINDOW_GAME, self)
|
net.SetPhaseWindow(net.PHASE_WINDOW_GAME, self)
|
||||||
@@ -227,7 +72,6 @@ class GameWindow(ui.ScriptWindow):
|
|||||||
self.quickSlotPageIndex = 0
|
self.quickSlotPageIndex = 0
|
||||||
self.lastPKModeSendedTime = 0
|
self.lastPKModeSendedTime = 0
|
||||||
self.pressNumber = None
|
self.pressNumber = None
|
||||||
self.headlessGmEnabled = _HeadlessGMEnabled()
|
|
||||||
|
|
||||||
self.guildWarQuestionDialog = None
|
self.guildWarQuestionDialog = None
|
||||||
self.interface = None
|
self.interface = None
|
||||||
@@ -238,16 +82,9 @@ class GameWindow(ui.ScriptWindow):
|
|||||||
self.playerGauge = None
|
self.playerGauge = None
|
||||||
|
|
||||||
self.stream = stream
|
self.stream = stream
|
||||||
if self.headlessGmEnabled:
|
self.interface = interfaceModule.Interface()
|
||||||
self.interface = _HeadlessInterface()
|
self.interface.MakeInterface()
|
||||||
_WriteHeadlessTrace("GameWindow.__init__ interface_headless")
|
self.interface.ShowDefaultWindows()
|
||||||
else:
|
|
||||||
self.interface = interfaceModule.Interface()
|
|
||||||
_WriteHeadlessTrace("GameWindow.__init__ interface")
|
|
||||||
self.interface.MakeInterface()
|
|
||||||
_WriteHeadlessTrace("GameWindow.__init__ interface_made")
|
|
||||||
self.interface.ShowDefaultWindows()
|
|
||||||
_WriteHeadlessTrace("GameWindow.__init__ default_windows")
|
|
||||||
|
|
||||||
self.curtain = uiPhaseCurtain.PhaseCurtain()
|
self.curtain = uiPhaseCurtain.PhaseCurtain()
|
||||||
self.curtain.speed = 0.03
|
self.curtain.speed = 0.03
|
||||||
@@ -275,7 +112,6 @@ class GameWindow(ui.ScriptWindow):
|
|||||||
|
|
||||||
self.__ServerCommand_Build()
|
self.__ServerCommand_Build()
|
||||||
self.__ProcessPreservedServerCommand()
|
self.__ProcessPreservedServerCommand()
|
||||||
_WriteHeadlessTrace("GameWindow.__init__ done")
|
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
player.SetGameWindow(0)
|
player.SetGameWindow(0)
|
||||||
@@ -297,10 +133,6 @@ class GameWindow(ui.ScriptWindow):
|
|||||||
self.enableXMasBoom = False
|
self.enableXMasBoom = False
|
||||||
self.startTimeXMasBoom = 0.0
|
self.startTimeXMasBoom = 0.0
|
||||||
self.indexXMasBoom = 0
|
self.indexXMasBoom = 0
|
||||||
currentMap = background.GetCurrentMapName()
|
|
||||||
_WriteHeadlessTrace("GameWindow.Open current_map=%s" % currentMap)
|
|
||||||
if self.headlessGmEnabled:
|
|
||||||
self.__HeadlessGMOnOpen(currentMap)
|
|
||||||
|
|
||||||
global cameraDistance, cameraPitch, cameraRotation, cameraHeight
|
global cameraDistance, cameraPitch, cameraRotation, cameraHeight
|
||||||
|
|
||||||
@@ -388,7 +220,6 @@ class GameWindow(ui.ScriptWindow):
|
|||||||
self.currentCubeNPC = 0
|
self.currentCubeNPC = 0
|
||||||
|
|
||||||
def Close(self):
|
def Close(self):
|
||||||
_WriteHeadlessTrace("GameWindow.Close begin current_map=%s" % background.GetCurrentMapName())
|
|
||||||
self.Hide()
|
self.Hide()
|
||||||
|
|
||||||
global cameraDistance, cameraPitch, cameraRotation, cameraHeight
|
global cameraDistance, cameraPitch, cameraRotation, cameraHeight
|
||||||
@@ -467,7 +298,6 @@ class GameWindow(ui.ScriptWindow):
|
|||||||
app.HideCursor()
|
app.HideCursor()
|
||||||
|
|
||||||
print("---------------------------------------------------------------------------- CLOSE GAME WINDOW")
|
print("---------------------------------------------------------------------------- CLOSE GAME WINDOW")
|
||||||
_WriteHeadlessTrace("GameWindow.Close end current_map=%s" % background.GetCurrentMapName())
|
|
||||||
|
|
||||||
def __BuildKeyDict(self):
|
def __BuildKeyDict(self):
|
||||||
onPressKeyDict = {}
|
onPressKeyDict = {}
|
||||||
@@ -1026,7 +856,6 @@ class GameWindow(ui.ScriptWindow):
|
|||||||
|
|
||||||
# SHOW_LOCAL_MAP_NAME
|
# SHOW_LOCAL_MAP_NAME
|
||||||
def ShowMapName(self, mapName, x, y):
|
def ShowMapName(self, mapName, x, y):
|
||||||
_WriteHeadlessTrace("ShowMapName map=%s x=%d y=%d" % (mapName, x, y))
|
|
||||||
|
|
||||||
if self.mapNameShower:
|
if self.mapNameShower:
|
||||||
self.mapNameShower.ShowMapName(mapName, x, y)
|
self.mapNameShower.ShowMapName(mapName, x, y)
|
||||||
@@ -1636,104 +1465,8 @@ class GameWindow(ui.ScriptWindow):
|
|||||||
def OnMouseMiddleButtonUp(self):
|
def OnMouseMiddleButtonUp(self):
|
||||||
player.SetMouseMiddleButtonState(player.MBS_CLICK)
|
player.SetMouseMiddleButtonState(player.MBS_CLICK)
|
||||||
|
|
||||||
def __HeadlessGMOnOpen(self, currentMap):
|
|
||||||
global HEADLESS_GM_STATE
|
|
||||||
|
|
||||||
state = HEADLESS_GM_STATE
|
|
||||||
now = app.GetTime()
|
|
||||||
|
|
||||||
if not state["initialized"]:
|
|
||||||
state["steps"] = _GetHeadlessWarpSteps()
|
|
||||||
state["index"] = 0
|
|
||||||
state["phase"] = "waiting_command"
|
|
||||||
state["command_at"] = now + _HeadlessGMCommandDelay()
|
|
||||||
state["deadline"] = 0.0
|
|
||||||
state["quit_requested"] = False
|
|
||||||
state["initialized"] = True
|
|
||||||
_WriteHeadlessTrace("GM ready current_map=%s steps=%d" % (currentMap, len(state["steps"])))
|
|
||||||
|
|
||||||
if not state["steps"]:
|
|
||||||
state["phase"] = "failed"
|
|
||||||
_HeadlessGMRequestQuit("No warp steps configured")
|
|
||||||
return
|
|
||||||
|
|
||||||
if state["phase"] != "waiting_open":
|
|
||||||
return
|
|
||||||
|
|
||||||
if state["index"] >= len(state["steps"]):
|
|
||||||
state["phase"] = "success"
|
|
||||||
_HeadlessGMRequestQuit("Scenario success current_map=%s" % currentMap)
|
|
||||||
return
|
|
||||||
|
|
||||||
expectedMap = state["steps"][state["index"]]["map_name"]
|
|
||||||
if currentMap != expectedMap:
|
|
||||||
state["phase"] = "failed"
|
|
||||||
_HeadlessGMRequestQuit("Warp open mismatch index=%d expected=%s current_map=%s" % (state["index"], expectedMap, currentMap))
|
|
||||||
return
|
|
||||||
|
|
||||||
_WriteHeadlessTrace("Warp arrived index=%d map=%s" % (state["index"], currentMap))
|
|
||||||
state["index"] += 1
|
|
||||||
|
|
||||||
if state["index"] >= len(state["steps"]):
|
|
||||||
state["phase"] = "success"
|
|
||||||
_HeadlessGMRequestQuit("Scenario success current_map=%s" % currentMap)
|
|
||||||
return
|
|
||||||
|
|
||||||
state["phase"] = "settling"
|
|
||||||
state["command_at"] = now + _HeadlessGMSettleDelay()
|
|
||||||
state["deadline"] = 0.0
|
|
||||||
|
|
||||||
def __HeadlessGMOnUpdate(self):
|
|
||||||
global HEADLESS_GM_STATE
|
|
||||||
|
|
||||||
if not self.headlessGmEnabled:
|
|
||||||
return
|
|
||||||
|
|
||||||
state = HEADLESS_GM_STATE
|
|
||||||
if not state["initialized"] or state["quit_requested"]:
|
|
||||||
return
|
|
||||||
|
|
||||||
now = app.GetTime()
|
|
||||||
|
|
||||||
if state["phase"] == "waiting_command":
|
|
||||||
if state["index"] >= len(state["steps"]):
|
|
||||||
state["phase"] = "success"
|
|
||||||
_HeadlessGMRequestQuit("Scenario success current_map=%s" % background.GetCurrentMapName())
|
|
||||||
return
|
|
||||||
|
|
||||||
if now < state["command_at"]:
|
|
||||||
return
|
|
||||||
|
|
||||||
if 0 == player.GetMainCharacterIndex():
|
|
||||||
return
|
|
||||||
|
|
||||||
step = state["steps"][state["index"]]
|
|
||||||
meterX = int(step["global_x"] / 100)
|
|
||||||
meterY = int(step["global_y"] / 100)
|
|
||||||
command = "/warp %d %d" % (meterX, meterY)
|
|
||||||
_WriteHeadlessTrace("Warp send index=%d map=%s meter_x=%d meter_y=%d current_map=%s" % (state["index"], step["map_name"], meterX, meterY, background.GetCurrentMapName()))
|
|
||||||
net.SendChatPacket(command)
|
|
||||||
state["phase"] = "waiting_open"
|
|
||||||
state["deadline"] = now + _HeadlessGMWarpTimeout()
|
|
||||||
return
|
|
||||||
|
|
||||||
if state["phase"] == "settling":
|
|
||||||
if now >= state["command_at"]:
|
|
||||||
state["phase"] = "waiting_command"
|
|
||||||
return
|
|
||||||
|
|
||||||
if state["phase"] == "waiting_open" and now > state["deadline"]:
|
|
||||||
if state["index"] < len(state["steps"]):
|
|
||||||
expectedMap = state["steps"][state["index"]]["map_name"]
|
|
||||||
else:
|
|
||||||
expectedMap = ""
|
|
||||||
state["phase"] = "failed"
|
|
||||||
_HeadlessGMRequestQuit("Warp timeout index=%d expected=%s current_map=%s" % (state["index"], expectedMap, background.GetCurrentMapName()))
|
|
||||||
return
|
|
||||||
|
|
||||||
def OnUpdate(self):
|
def OnUpdate(self):
|
||||||
app.UpdateGame()
|
app.UpdateGame()
|
||||||
self.__HeadlessGMOnUpdate()
|
|
||||||
|
|
||||||
if self.mapNameShower.IsShow():
|
if self.mapNameShower.IsShow():
|
||||||
self.mapNameShower.Update()
|
self.mapNameShower.Update()
|
||||||
@@ -2180,10 +1913,6 @@ class GameWindow(ui.ScriptWindow):
|
|||||||
"PartyRequestDenied" : self.__PartyRequestDenied,
|
"PartyRequestDenied" : self.__PartyRequestDenied,
|
||||||
"horse_state" : self.__Horse_UpdateState,
|
"horse_state" : self.__Horse_UpdateState,
|
||||||
"hide_horse_state" : self.__Horse_HideState,
|
"hide_horse_state" : self.__Horse_HideState,
|
||||||
"AutoPickupState" : self.__AutoPickupState,
|
|
||||||
"StoneQueueState" : self.__StoneQueueState,
|
|
||||||
"SwitchbotState" : self.__SwitchbotState,
|
|
||||||
"SwitchbotSlot" : self.__SwitchbotSlot,
|
|
||||||
"WarUC" : self.__GuildWar_UpdateMemberCount,
|
"WarUC" : self.__GuildWar_UpdateMemberCount,
|
||||||
"test_server" : self.__EnableTestServerFlag,
|
"test_server" : self.__EnableTestServerFlag,
|
||||||
"mall" : self.__InGameShop_Show,
|
"mall" : self.__InGameShop_Show,
|
||||||
@@ -2231,18 +1960,6 @@ class GameWindow(ui.ScriptWindow):
|
|||||||
def PartyHealReady(self):
|
def PartyHealReady(self):
|
||||||
self.interface.PartyHealReady()
|
self.interface.PartyHealReady()
|
||||||
|
|
||||||
def __AutoPickupState(self, enabled, mode, mask, vip):
|
|
||||||
uiAutopickup.SetAutoPickupState(int(enabled), int(mode), int(mask), int(vip))
|
|
||||||
|
|
||||||
def __StoneQueueState(self, maxCount, active, current, success, fail):
|
|
||||||
uiStoneQueue.SetStoneQueueState(int(maxCount), int(active), int(current), int(success), int(fail))
|
|
||||||
|
|
||||||
def __SwitchbotState(self, speedIndex, activeCount, scrollCount, etaSeconds):
|
|
||||||
uiSwitchbot.SetSwitchbotState(int(speedIndex), int(activeCount), int(scrollCount), int(etaSeconds))
|
|
||||||
|
|
||||||
def __SwitchbotSlot(self, slotIndex, active, itemCell, attrType, minValue, attempts):
|
|
||||||
uiSwitchbot.SetSwitchbotSlotState(int(slotIndex), int(active), int(itemCell), int(attrType), int(minValue), int(attempts))
|
|
||||||
|
|
||||||
def AskSafeboxPassword(self):
|
def AskSafeboxPassword(self):
|
||||||
self.interface.AskSafeboxPassword()
|
self.interface.AskSafeboxPassword()
|
||||||
|
|
||||||
@@ -2512,3 +2229,4 @@ class GameWindow(ui.ScriptWindow):
|
|||||||
|
|
||||||
def SkillClearCoolTime(self, slotIndex):
|
def SkillClearCoolTime(self, slotIndex):
|
||||||
self.interface.SkillClearCoolTime(slotIndex)
|
self.interface.SkillClearCoolTime(slotIndex)
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,6 @@ import uiSystem
|
|||||||
import uiRestart
|
import uiRestart
|
||||||
import uiToolTip
|
import uiToolTip
|
||||||
import uiMiniMap
|
import uiMiniMap
|
||||||
import uiBiolog
|
|
||||||
import uiTeleport
|
|
||||||
import uiSwitchbot
|
|
||||||
import uiParty
|
import uiParty
|
||||||
import uiSafebox
|
import uiSafebox
|
||||||
import uiGuild
|
import uiGuild
|
||||||
@@ -78,9 +75,6 @@ class Interface(object):
|
|||||||
self.wndChat = None
|
self.wndChat = None
|
||||||
self.wndMessenger = None
|
self.wndMessenger = None
|
||||||
self.wndMiniMap = None
|
self.wndMiniMap = None
|
||||||
self.wndBiolog = None
|
|
||||||
self.wndTeleport = None
|
|
||||||
self.wndSwitchbot = None
|
|
||||||
self.wndGuild = None
|
self.wndGuild = None
|
||||||
self.wndGuildBuilding = None
|
self.wndGuildBuilding = None
|
||||||
|
|
||||||
@@ -186,9 +180,6 @@ class Interface(object):
|
|||||||
wndDragonSoulRefine = None
|
wndDragonSoulRefine = None
|
||||||
|
|
||||||
wndMiniMap = uiMiniMap.MiniMap()
|
wndMiniMap = uiMiniMap.MiniMap()
|
||||||
wndBiolog = uiBiolog.BiologWindow()
|
|
||||||
wndTeleport = uiTeleport.TeleportWindow()
|
|
||||||
wndSwitchbot = uiSwitchbot.SwitchbotWindow()
|
|
||||||
wndSafebox = uiSafebox.SafeboxWindow()
|
wndSafebox = uiSafebox.SafeboxWindow()
|
||||||
|
|
||||||
# ITEM_MALL
|
# ITEM_MALL
|
||||||
@@ -204,14 +195,8 @@ class Interface(object):
|
|||||||
self.wndDragonSoul = wndDragonSoul
|
self.wndDragonSoul = wndDragonSoul
|
||||||
self.wndDragonSoulRefine = wndDragonSoulRefine
|
self.wndDragonSoulRefine = wndDragonSoulRefine
|
||||||
self.wndMiniMap = wndMiniMap
|
self.wndMiniMap = wndMiniMap
|
||||||
self.wndBiolog = wndBiolog
|
|
||||||
self.wndTeleport = wndTeleport
|
|
||||||
self.wndSwitchbot = wndSwitchbot
|
|
||||||
self.wndSafebox = wndSafebox
|
self.wndSafebox = wndSafebox
|
||||||
self.wndChatLog = wndChatLog
|
self.wndChatLog = wndChatLog
|
||||||
self.wndMiniMap.SetBiologButtonEvent(ui.__mem_func__(self.ToggleBiologWindow))
|
|
||||||
self.wndMiniMap.SetTeleportButtonEvent(ui.__mem_func__(self.ToggleTeleportWindow))
|
|
||||||
self.wndMiniMap.SetSwitchbotButtonEvent(ui.__mem_func__(self.ToggleSwitchbotWindow))
|
|
||||||
|
|
||||||
if app.ENABLE_DRAGON_SOUL_SYSTEM:
|
if app.ENABLE_DRAGON_SOUL_SYSTEM:
|
||||||
self.wndDragonSoul.SetDragonSoulRefineWindow(self.wndDragonSoulRefine)
|
self.wndDragonSoul.SetDragonSoulRefineWindow(self.wndDragonSoulRefine)
|
||||||
@@ -424,11 +409,6 @@ class Interface(object):
|
|||||||
if self.wndMiniMap:
|
if self.wndMiniMap:
|
||||||
self.wndMiniMap.Destroy()
|
self.wndMiniMap.Destroy()
|
||||||
|
|
||||||
if self.wndBiolog:
|
|
||||||
self.wndBiolog.Hide()
|
|
||||||
if self.wndSwitchbot:
|
|
||||||
self.wndSwitchbot.Hide()
|
|
||||||
|
|
||||||
if self.wndSafebox:
|
if self.wndSafebox:
|
||||||
self.wndSafebox.Destroy()
|
self.wndSafebox.Destroy()
|
||||||
|
|
||||||
@@ -519,8 +499,6 @@ class Interface(object):
|
|||||||
del self.tooltipItem
|
del self.tooltipItem
|
||||||
del self.tooltipSkill
|
del self.tooltipSkill
|
||||||
del self.wndMiniMap
|
del self.wndMiniMap
|
||||||
del self.wndBiolog
|
|
||||||
del self.wndSwitchbot
|
|
||||||
del self.wndSafebox
|
del self.wndSafebox
|
||||||
del self.wndMall
|
del self.wndMall
|
||||||
del self.wndParty
|
del self.wndParty
|
||||||
@@ -880,9 +858,6 @@ class Interface(object):
|
|||||||
if self.wndMiniMap:
|
if self.wndMiniMap:
|
||||||
self.wndMiniMap.Hide()
|
self.wndMiniMap.Hide()
|
||||||
|
|
||||||
if self.wndBiolog:
|
|
||||||
self.wndBiolog.Hide()
|
|
||||||
|
|
||||||
if self.wndMessenger:
|
if self.wndMessenger:
|
||||||
self.wndMessenger.Hide()
|
self.wndMessenger.Hide()
|
||||||
|
|
||||||
@@ -967,33 +942,6 @@ class Interface(object):
|
|||||||
def MiniMapScaleDown(self):
|
def MiniMapScaleDown(self):
|
||||||
self.wndMiniMap.ScaleDown()
|
self.wndMiniMap.ScaleDown()
|
||||||
|
|
||||||
def ToggleBiologWindow(self):
|
|
||||||
if False == self.wndBiolog.IsShow():
|
|
||||||
(miniMapX, miniMapY) = self.wndMiniMap.GetGlobalPosition()
|
|
||||||
self.wndBiolog.SetPosition(max(10, miniMapX - self.wndBiolog.GetWidth() - 10), miniMapY + 8)
|
|
||||||
self.wndBiolog.Show()
|
|
||||||
self.wndBiolog.SetTop()
|
|
||||||
else:
|
|
||||||
self.wndBiolog.Hide()
|
|
||||||
|
|
||||||
def ToggleTeleportWindow(self):
|
|
||||||
if False == self.wndTeleport.IsShow():
|
|
||||||
(miniMapX, miniMapY) = self.wndMiniMap.GetGlobalPosition()
|
|
||||||
self.wndTeleport.SetPosition(max(10, miniMapX - self.wndTeleport.GetWidth() - 10), miniMapY + 24)
|
|
||||||
self.wndTeleport.Show()
|
|
||||||
self.wndTeleport.SetTop()
|
|
||||||
else:
|
|
||||||
self.wndTeleport.Hide()
|
|
||||||
|
|
||||||
def ToggleSwitchbotWindow(self):
|
|
||||||
if False == self.wndSwitchbot.IsShow():
|
|
||||||
(miniMapX, miniMapY) = self.wndMiniMap.GetGlobalPosition()
|
|
||||||
self.wndSwitchbot.SetPosition(max(10, miniMapX - self.wndSwitchbot.GetWidth() - 10), miniMapY + 40)
|
|
||||||
self.wndSwitchbot.Show()
|
|
||||||
self.wndSwitchbot.SetTop()
|
|
||||||
else:
|
|
||||||
self.wndSwitchbot.Hide()
|
|
||||||
|
|
||||||
def ToggleCharacterWindow(self, state):
|
def ToggleCharacterWindow(self, state):
|
||||||
if False == player.IsObserverMode():
|
if False == player.IsObserverMode():
|
||||||
if False == self.wndCharacter.IsShow():
|
if False == self.wndCharacter.IsShow():
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
import ui
|
import ui
|
||||||
import uiScriptLocale
|
import uiScriptLocale
|
||||||
import net
|
import net
|
||||||
@@ -37,25 +35,6 @@ import uiOption
|
|||||||
import uiRestart
|
import uiRestart
|
||||||
####################################
|
####################################
|
||||||
|
|
||||||
|
|
||||||
def _GetHeadlessScenario():
|
|
||||||
return os.environ.get("M2_HEADLESS_SCENARIO", "").strip().lower()
|
|
||||||
|
|
||||||
|
|
||||||
def _WriteHeadlessTrace(message):
|
|
||||||
scenario = _GetHeadlessScenario()
|
|
||||||
if scenario == "map_load":
|
|
||||||
tracePath = "log/headless_map_load_trace.txt"
|
|
||||||
elif scenario == "gm_teleport":
|
|
||||||
tracePath = "log/headless_gm_teleport_trace.txt"
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
open(tracePath, "a").write("%s\n" % message)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
class LoadingWindow(ui.ScriptWindow):
|
class LoadingWindow(ui.ScriptWindow):
|
||||||
def __init__(self, stream):
|
def __init__(self, stream):
|
||||||
print("NEW LOADING WINDOW -------------------------------------------------------------------------------")
|
print("NEW LOADING WINDOW -------------------------------------------------------------------------------")
|
||||||
@@ -239,7 +218,6 @@ class LoadingWindow(ui.ScriptWindow):
|
|||||||
try:
|
try:
|
||||||
runFunc()
|
runFunc()
|
||||||
except:
|
except:
|
||||||
_WriteHeadlessTrace("LoadData failure step=%d" % progress)
|
|
||||||
self.errMsg.Show()
|
self.errMsg.Show()
|
||||||
self.loadStepList=[]
|
self.loadStepList=[]
|
||||||
|
|
||||||
@@ -324,9 +302,7 @@ class LoadingWindow(ui.ScriptWindow):
|
|||||||
emotion.RegisterEmotionIcons()
|
emotion.RegisterEmotionIcons()
|
||||||
|
|
||||||
def __LoadMap(self):
|
def __LoadMap(self):
|
||||||
_WriteHeadlessTrace("LoadMap begin global_x=%d global_y=%d" % (self.playerX, self.playerY))
|
|
||||||
net.Warp(self.playerX, self.playerY)
|
net.Warp(self.playerX, self.playerY)
|
||||||
_WriteHeadlessTrace("LoadMap current_map=%s" % background.GetCurrentMapName())
|
|
||||||
|
|
||||||
def __LoadSound(self):
|
def __LoadSound(self):
|
||||||
playerSettingModule.LoadGameData("SOUND")
|
playerSettingModule.LoadGameData("SOUND")
|
||||||
@@ -361,7 +337,6 @@ class LoadingWindow(ui.ScriptWindow):
|
|||||||
# END_OF_GUILD_BUILDING
|
# END_OF_GUILD_BUILDING
|
||||||
|
|
||||||
def __StartGame(self):
|
def __StartGame(self):
|
||||||
_WriteHeadlessTrace("StartGame begin current_map=%s" % background.GetCurrentMapName())
|
|
||||||
background.SetViewDistanceSet(background.DISTANCE0, 25600)
|
background.SetViewDistanceSet(background.DISTANCE0, 25600)
|
||||||
"""
|
"""
|
||||||
background.SetViewDistanceSet(background.DISTANCE1, 19200)
|
background.SetViewDistanceSet(background.DISTANCE1, 19200)
|
||||||
@@ -374,7 +349,6 @@ class LoadingWindow(ui.ScriptWindow):
|
|||||||
app.SetGlobalCenterPosition(self.playerX, self.playerY)
|
app.SetGlobalCenterPosition(self.playerX, self.playerY)
|
||||||
|
|
||||||
net.StartGame()
|
net.StartGame()
|
||||||
_WriteHeadlessTrace("StartGame queued current_map=%s" % background.GetCurrentMapName())
|
|
||||||
|
|
||||||
def _ReloadTitleNames():
|
def _ReloadTitleNames():
|
||||||
for i in range(len(localeInfo.TITLE_NAME_LIST)):
|
for i in range(len(localeInfo.TITLE_NAME_LIST)):
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import os
|
|
||||||
import dbg
|
import dbg
|
||||||
import app
|
import app
|
||||||
import net
|
import net
|
||||||
@@ -19,10 +18,6 @@ import ime
|
|||||||
import uiScriptLocale
|
import uiScriptLocale
|
||||||
import debugInfo
|
import debugInfo
|
||||||
|
|
||||||
|
|
||||||
def _AllowHeadlessLoginInfo():
|
|
||||||
return os.environ.get("M2_HEADLESS_SCENARIO", "").strip().lower() == "gm_teleport"
|
|
||||||
|
|
||||||
# Multi-language hot-reload system
|
# Multi-language hot-reload system
|
||||||
from uilocaleselector import LocaleSelector
|
from uilocaleselector import LocaleSelector
|
||||||
|
|
||||||
@@ -720,7 +715,7 @@ class LoginWindow(ui.ScriptWindow):
|
|||||||
|
|
||||||
def __LoadLoginInfo(self, loginInfoFileName):
|
def __LoadLoginInfo(self, loginInfoFileName):
|
||||||
# This should not work in production
|
# This should not work in production
|
||||||
if not debugInfo.IsDebugMode() and not _AllowHeadlessLoginInfo():
|
if not debugInfo.IsDebugMode():
|
||||||
app.loggined = FALSE
|
app.loggined = FALSE
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
###################################################################################################
|
###################################################################################################
|
||||||
# Network
|
# Network
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
import app
|
import app
|
||||||
import chr
|
import chr
|
||||||
import dbg
|
import dbg
|
||||||
@@ -20,25 +18,6 @@ import uiPhaseCurtain
|
|||||||
|
|
||||||
import localeInfo
|
import localeInfo
|
||||||
|
|
||||||
|
|
||||||
def _GetHeadlessScenario():
|
|
||||||
return os.environ.get("M2_HEADLESS_SCENARIO", "").strip().lower()
|
|
||||||
|
|
||||||
|
|
||||||
def _WriteHeadlessTrace(message):
|
|
||||||
scenario = _GetHeadlessScenario()
|
|
||||||
if scenario == "map_load":
|
|
||||||
tracePath = "log/headless_map_load_trace.txt"
|
|
||||||
elif scenario == "gm_teleport":
|
|
||||||
tracePath = "log/headless_gm_teleport_trace.txt"
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
open(tracePath, "a").write("%s\n" % message)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
class PopupDialog(ui.ScriptWindow):
|
class PopupDialog(ui.ScriptWindow):
|
||||||
# MR-15: Multiline dialog messages
|
# MR-15: Multiline dialog messages
|
||||||
BASE_HEIGHT = 105
|
BASE_HEIGHT = 105
|
||||||
@@ -188,7 +167,6 @@ class MainStream(object):
|
|||||||
|
|
||||||
if newPhaseWindow:
|
if newPhaseWindow:
|
||||||
newPhaseWindow.Open()
|
newPhaseWindow.Open()
|
||||||
_WriteHeadlessTrace("MainStream.ChangePhase opened=%s" % newPhaseWindow.__class__.__name__)
|
|
||||||
|
|
||||||
self.curPhaseWindow=newPhaseWindow
|
self.curPhaseWindow=newPhaseWindow
|
||||||
|
|
||||||
@@ -259,7 +237,7 @@ class MainStream(object):
|
|||||||
try:
|
try:
|
||||||
import introLoading
|
import introLoading
|
||||||
loadingPhaseWindow=introLoading.LoadingWindow(self)
|
loadingPhaseWindow=introLoading.LoadingWindow(self)
|
||||||
loadingPhaseWindow.DEBUG_LoadData(x, y)
|
loadingPhaseWindow.LoadData(x, y)
|
||||||
self.SetPhaseWindow(loadingPhaseWindow)
|
self.SetPhaseWindow(loadingPhaseWindow)
|
||||||
except:
|
except:
|
||||||
import exception
|
import exception
|
||||||
@@ -278,10 +256,8 @@ class MainStream(object):
|
|||||||
def SetGamePhase(self):
|
def SetGamePhase(self):
|
||||||
try:
|
try:
|
||||||
import game
|
import game
|
||||||
_WriteHeadlessTrace("MainStream.SetGamePhase begin current_map=%s" % background.GetCurrentMapName())
|
|
||||||
self.popupWindow.Close()
|
self.popupWindow.Close()
|
||||||
self.SetPhaseWindow(game.GameWindow(self))
|
self.SetPhaseWindow(game.GameWindow(self))
|
||||||
_WriteHeadlessTrace("MainStream.SetGamePhase queued current_map=%s" % background.GetCurrentMapName())
|
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
import exception
|
import exception
|
||||||
|
|||||||
@@ -659,7 +659,6 @@ def __LoadGameWarriorEx(race, path):
|
|||||||
|
|
||||||
## Bone
|
## Bone
|
||||||
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON, "equip_right_hand")
|
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON, "equip_right_hand")
|
||||||
chrmgr.RegisterAttachingBoneName(chr.PART_ACCE, "Bip01 Spine2")
|
|
||||||
|
|
||||||
def __LoadGameAssassinEx(race, path):
|
def __LoadGameAssassinEx(race, path):
|
||||||
## Assassin
|
## Assassin
|
||||||
@@ -873,7 +872,6 @@ def __LoadGameAssassinEx(race, path):
|
|||||||
|
|
||||||
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON, "equip_right")
|
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON, "equip_right")
|
||||||
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON_LEFT, "equip_left")
|
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON_LEFT, "equip_left")
|
||||||
chrmgr.RegisterAttachingBoneName(chr.PART_ACCE, "Bip01 Spine2")
|
|
||||||
|
|
||||||
def __LoadGameSuraEx(race, path):
|
def __LoadGameSuraEx(race, path):
|
||||||
## Sura
|
## Sura
|
||||||
@@ -1191,7 +1189,6 @@ def __LoadGameShamanEx(race, path):
|
|||||||
|
|
||||||
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON, "equip_right")
|
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON, "equip_right")
|
||||||
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON_LEFT, "equip_left")
|
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON_LEFT, "equip_left")
|
||||||
chrmgr.RegisterAttachingBoneName(chr.PART_ACCE, "Bip01 Spine2")
|
|
||||||
|
|
||||||
|
|
||||||
def __LoadGameSkill():
|
def __LoadGameSkill():
|
||||||
@@ -1459,4 +1456,4 @@ def SetGuildBuilding(race, name, grade):
|
|||||||
chrmgr.SetPathName("d:/ymir work/guild/building/%s/" % name)
|
chrmgr.SetPathName("d:/ymir work/guild/building/%s/" % name)
|
||||||
chrmgr.LoadRaceData("%s%02d.msm" % (name, grade))
|
chrmgr.LoadRaceData("%s%02d.msm" % (name, grade))
|
||||||
chrmgr.RegisterMotionMode(chr.MOTION_MODE_GENERAL)
|
chrmgr.RegisterMotionMode(chr.MOTION_MODE_GENERAL)
|
||||||
#chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_DEAD, name + "_destruction.msa")
|
#chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_DEAD, name + "_destruction.msa")
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
import dbg
|
import dbg
|
||||||
import app
|
import app
|
||||||
import localeInfo
|
import localeInfo
|
||||||
@@ -16,66 +14,6 @@ import stringCommander
|
|||||||
|
|
||||||
#bind_me(locals().values())
|
#bind_me(locals().values())
|
||||||
|
|
||||||
|
|
||||||
def _GetHeadlessScenario():
|
|
||||||
return os.environ.get("M2_HEADLESS_SCENARIO", "").strip().lower()
|
|
||||||
|
|
||||||
|
|
||||||
def _WriteHeadlessTrace(message):
|
|
||||||
scenario = _GetHeadlessScenario()
|
|
||||||
if scenario == "map_load":
|
|
||||||
tracePath = "log/headless_map_load_trace.txt"
|
|
||||||
elif scenario == "gm_teleport":
|
|
||||||
tracePath = "log/headless_gm_teleport_trace.txt"
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
open(tracePath, "a").write("%s\n" % message)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def _GetHeadlessInt(name, default):
|
|
||||||
try:
|
|
||||||
return int(os.environ.get(name, str(default)))
|
|
||||||
except (TypeError, ValueError):
|
|
||||||
return default
|
|
||||||
|
|
||||||
|
|
||||||
def _ApplyRenderFPSOverride():
|
|
||||||
rawValue = os.environ.get("M2_RENDER_FPS", "").strip()
|
|
||||||
if not rawValue:
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
fps = int(rawValue)
|
|
||||||
except (TypeError, ValueError):
|
|
||||||
_WriteHeadlessTrace("Invalid M2_RENDER_FPS=%s" % rawValue)
|
|
||||||
return
|
|
||||||
|
|
||||||
app.SetFPS(fps)
|
|
||||||
_WriteHeadlessTrace("Render FPS override=%d" % fps)
|
|
||||||
|
|
||||||
|
|
||||||
def _SetInitialPhase(mainStream):
|
|
||||||
scenario = _GetHeadlessScenario()
|
|
||||||
if scenario == "map_load":
|
|
||||||
mapName = os.environ.get("M2_HEADLESS_MAP_NAME", "").strip()
|
|
||||||
globalX = _GetHeadlessInt("M2_HEADLESS_GLOBAL_X", 460800)
|
|
||||||
globalY = _GetHeadlessInt("M2_HEADLESS_GLOBAL_Y", 960000)
|
|
||||||
|
|
||||||
_WriteHeadlessTrace("Scenario begin map=%s global_x=%d global_y=%d" % (mapName, globalX, globalY))
|
|
||||||
mainStream.SetTestGamePhase(globalX, globalY)
|
|
||||||
return
|
|
||||||
|
|
||||||
if scenario == "gm_teleport":
|
|
||||||
_WriteHeadlessTrace("Scenario begin gm_teleport")
|
|
||||||
mainStream.SetLoginPhase()
|
|
||||||
return
|
|
||||||
|
|
||||||
mainStream.SetLoginPhase()
|
|
||||||
|
|
||||||
def RunApp():
|
def RunApp():
|
||||||
musicInfo.LoadLastPlayFieldMusic()
|
musicInfo.LoadLastPlayFieldMusic()
|
||||||
|
|
||||||
@@ -98,7 +36,6 @@ def RunApp():
|
|||||||
return
|
return
|
||||||
|
|
||||||
app.SetCamera(1500.0, 30.0, 0.0, 180.0)
|
app.SetCamera(1500.0, 30.0, 0.0, 180.0)
|
||||||
_ApplyRenderFPSOverride()
|
|
||||||
|
|
||||||
#Gets and sets the floating-point control word
|
#Gets and sets the floating-point control word
|
||||||
#app.SetControlFP()
|
#app.SetControlFP()
|
||||||
@@ -110,7 +47,8 @@ def RunApp():
|
|||||||
mainStream.Create()
|
mainStream.Create()
|
||||||
|
|
||||||
#mainStream.SetLoadingPhase()
|
#mainStream.SetLoadingPhase()
|
||||||
_SetInitialPhase(mainStream)
|
|
||||||
|
mainStream.SetLoginPhase()
|
||||||
#mainStream.SetSelectCharacterPhase()
|
#mainStream.SetSelectCharacterPhase()
|
||||||
#mainStream.SetCreateCharacterPhase()
|
#mainStream.SetCreateCharacterPhase()
|
||||||
#mainStream.SetSelectEmpirePhase()
|
#mainStream.SetSelectEmpirePhase()
|
||||||
@@ -120,3 +58,4 @@ def RunApp():
|
|||||||
mainStream.Destroy()
|
mainStream.Destroy()
|
||||||
|
|
||||||
RunApp()
|
RunApp()
|
||||||
|
|
||||||
|
|||||||
@@ -1,145 +0,0 @@
|
|||||||
import net
|
|
||||||
import ui
|
|
||||||
|
|
||||||
|
|
||||||
STATE_ENABLED = 0
|
|
||||||
STATE_MODE = 0
|
|
||||||
STATE_MASK = 31
|
|
||||||
STATE_VIP = 0
|
|
||||||
OPEN_WINDOWS = []
|
|
||||||
|
|
||||||
FILTERS = (
|
|
||||||
(1, "Weapons"),
|
|
||||||
(2, "Armor"),
|
|
||||||
(4, "Yang"),
|
|
||||||
(8, "Stones"),
|
|
||||||
(16, "Materials"),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def SetAutoPickupState(enabled, mode, mask, vip):
|
|
||||||
global STATE_ENABLED
|
|
||||||
global STATE_MODE
|
|
||||||
global STATE_MASK
|
|
||||||
global STATE_VIP
|
|
||||||
|
|
||||||
STATE_ENABLED = 1 if int(enabled) else 0
|
|
||||||
STATE_MODE = 1 if int(mode) else 0
|
|
||||||
STATE_MASK = int(mask) & 31
|
|
||||||
STATE_VIP = 1 if int(vip) else 0
|
|
||||||
|
|
||||||
for window in OPEN_WINDOWS:
|
|
||||||
try:
|
|
||||||
window.ApplyState()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class AutoPickupWindow(ui.BoardWithTitleBar):
|
|
||||||
def __init__(self):
|
|
||||||
ui.BoardWithTitleBar.__init__(self)
|
|
||||||
|
|
||||||
OPEN_WINDOWS.append(self)
|
|
||||||
|
|
||||||
self.filterButtons = {}
|
|
||||||
|
|
||||||
self.AddFlag("float")
|
|
||||||
self.AddFlag("movable")
|
|
||||||
self.SetSize(280, 248)
|
|
||||||
self.SetTitleName("Auto Pickup")
|
|
||||||
self.SetCloseEvent(self.Hide)
|
|
||||||
|
|
||||||
self.__CreateChildren()
|
|
||||||
self.Hide()
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
if self in OPEN_WINDOWS:
|
|
||||||
OPEN_WINDOWS.remove(self)
|
|
||||||
ui.BoardWithTitleBar.__del__(self)
|
|
||||||
|
|
||||||
def Destroy(self):
|
|
||||||
if self in OPEN_WINDOWS:
|
|
||||||
OPEN_WINDOWS.remove(self)
|
|
||||||
self.ClearDictionary()
|
|
||||||
self.filterButtons = {}
|
|
||||||
|
|
||||||
def __CreateChildren(self):
|
|
||||||
self.statusLine = self.__CreateLine(15, 36)
|
|
||||||
self.rangeLine = self.__CreateLine(15, 56)
|
|
||||||
self.modeLine = self.__CreateLine(15, 76)
|
|
||||||
self.noteLine = self.__CreateLine(15, 96)
|
|
||||||
|
|
||||||
self.enableButton = self.__CreateButton(170, 34, 90, "Enable")
|
|
||||||
self.enableButton.SetEvent(self.__ToggleEnabled)
|
|
||||||
|
|
||||||
self.whitelistButton = self.__CreateButton(15, 118, 118, "Whitelist")
|
|
||||||
self.whitelistButton.SetEvent(self.__SetMode, 0)
|
|
||||||
|
|
||||||
self.blacklistButton = self.__CreateButton(142, 118, 118, "Blacklist")
|
|
||||||
self.blacklistButton.SetEvent(self.__SetMode, 1)
|
|
||||||
|
|
||||||
for index, filterData in enumerate(FILTERS):
|
|
||||||
(bit, label) = filterData
|
|
||||||
button = self.__CreateButton(15, 150 + index * 18, 245, label)
|
|
||||||
button.SetEvent(self.__ToggleFilter, bit)
|
|
||||||
self.filterButtons[bit] = button
|
|
||||||
|
|
||||||
def __CreateLine(self, x, y):
|
|
||||||
textLine = ui.TextLine()
|
|
||||||
textLine.SetParent(self)
|
|
||||||
textLine.SetPosition(x, y)
|
|
||||||
textLine.SetOutline()
|
|
||||||
textLine.Show()
|
|
||||||
return textLine
|
|
||||||
|
|
||||||
def __CreateButton(self, x, y, width, text):
|
|
||||||
button = ui.Button()
|
|
||||||
button.SetParent(self)
|
|
||||||
button.SetPosition(x, y)
|
|
||||||
button.SetUpVisual("d:/ymir work/ui/public/small_thin_button_01.sub")
|
|
||||||
button.SetOverVisual("d:/ymir work/ui/public/small_thin_button_02.sub")
|
|
||||||
button.SetDownVisual("d:/ymir work/ui/public/small_thin_button_03.sub")
|
|
||||||
button.SetDisableVisual("d:/ymir work/ui/public/small_thin_button_01.sub")
|
|
||||||
button.SetSize(width, 17)
|
|
||||||
button.SetText(text)
|
|
||||||
button.Show()
|
|
||||||
return button
|
|
||||||
|
|
||||||
def __Send(self, command):
|
|
||||||
net.SendChatPacket(command, 0)
|
|
||||||
|
|
||||||
def __ToggleEnabled(self):
|
|
||||||
SetAutoPickupState(0 if STATE_ENABLED else 1, STATE_MODE, STATE_MASK, STATE_VIP)
|
|
||||||
self.__Send("/autopickup enable %d" % STATE_ENABLED)
|
|
||||||
|
|
||||||
def __SetMode(self, mode):
|
|
||||||
SetAutoPickupState(STATE_ENABLED, mode, STATE_MASK, STATE_VIP)
|
|
||||||
self.__Send("/autopickup mode %s" % ("blacklist" if mode else "whitelist"))
|
|
||||||
|
|
||||||
def __ToggleFilter(self, bit):
|
|
||||||
mask = STATE_MASK ^ bit
|
|
||||||
SetAutoPickupState(STATE_ENABLED, STATE_MODE, mask, STATE_VIP)
|
|
||||||
self.__Send("/autopickup mask %d" % STATE_MASK)
|
|
||||||
|
|
||||||
def ApplyState(self):
|
|
||||||
self.statusLine.SetText("Status: %s" % ("Enabled" if STATE_ENABLED else "Disabled"))
|
|
||||||
self.rangeLine.SetText("Range: %s" % ("VIP 300 / Free 220" if STATE_VIP else "Free 220"))
|
|
||||||
self.modeLine.SetText("Mode: %s" % ("Blacklist" if STATE_MODE else "Whitelist"))
|
|
||||||
self.noteLine.SetText("Only nearby owned drops are valid")
|
|
||||||
self.enableButton.SetText("Disable" if STATE_ENABLED else "Enable")
|
|
||||||
|
|
||||||
if STATE_MODE == 0:
|
|
||||||
self.whitelistButton.Down()
|
|
||||||
self.blacklistButton.SetUp()
|
|
||||||
else:
|
|
||||||
self.whitelistButton.SetUp()
|
|
||||||
self.blacklistButton.Down()
|
|
||||||
|
|
||||||
for (bit, label) in FILTERS:
|
|
||||||
prefix = "[x]" if (STATE_MASK & bit) else "[ ]"
|
|
||||||
self.filterButtons[bit].SetText("%s %s" % (prefix, label))
|
|
||||||
|
|
||||||
def Show(self):
|
|
||||||
self.__Send("/autopickup sync")
|
|
||||||
self.ApplyState()
|
|
||||||
ui.BoardWithTitleBar.Show(self)
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
import time
|
|
||||||
|
|
||||||
import net
|
|
||||||
import player
|
|
||||||
import quest
|
|
||||||
import ui
|
|
||||||
|
|
||||||
|
|
||||||
class BiologWindow(ui.BoardWithTitleBar):
|
|
||||||
TITLE_PREFIX = "Biolog Stage "
|
|
||||||
STAGE_TARGETS = {
|
|
||||||
1 : 10,
|
|
||||||
2 : 15,
|
|
||||||
3 : 20,
|
|
||||||
4 : 20,
|
|
||||||
5 : 25,
|
|
||||||
6 : 30,
|
|
||||||
7 : 30,
|
|
||||||
8 : 40,
|
|
||||||
9 : 40,
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
ui.BoardWithTitleBar.__init__(self)
|
|
||||||
|
|
||||||
self.lastRefreshTime = 0.0
|
|
||||||
|
|
||||||
self.AddFlag("float")
|
|
||||||
self.AddFlag("movable")
|
|
||||||
self.SetSize(230, 165)
|
|
||||||
self.SetTitleName("Biolog")
|
|
||||||
self.SetCloseEvent(self.Hide)
|
|
||||||
|
|
||||||
self.__CreateChildren()
|
|
||||||
self.Hide()
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
ui.BoardWithTitleBar.__del__(self)
|
|
||||||
|
|
||||||
def __CreateChildren(self):
|
|
||||||
self.statusLine = self.__CreateValueLine(15, 36)
|
|
||||||
self.stageLine = self.__CreateValueLine(15, 58)
|
|
||||||
self.itemLine = self.__CreateValueLine(15, 80)
|
|
||||||
self.progressLine = self.__CreateValueLine(15, 102)
|
|
||||||
self.cooldownLine = self.__CreateValueLine(15, 124)
|
|
||||||
|
|
||||||
submitButton = ui.Button()
|
|
||||||
submitButton.SetParent(self)
|
|
||||||
submitButton.SetPosition(134, 132)
|
|
||||||
submitButton.SetUpVisual("d:/ymir work/ui/public/small_thin_button_01.sub")
|
|
||||||
submitButton.SetOverVisual("d:/ymir work/ui/public/small_thin_button_02.sub")
|
|
||||||
submitButton.SetDownVisual("d:/ymir work/ui/public/small_thin_button_03.sub")
|
|
||||||
submitButton.SetText("Submit")
|
|
||||||
submitButton.SetEvent(self.__OnSubmit)
|
|
||||||
submitButton.Show()
|
|
||||||
self.submitButton = submitButton
|
|
||||||
|
|
||||||
def __CreateValueLine(self, x, y):
|
|
||||||
textLine = ui.TextLine()
|
|
||||||
textLine.SetParent(self)
|
|
||||||
textLine.SetPosition(x, y)
|
|
||||||
textLine.SetOutline()
|
|
||||||
textLine.Show()
|
|
||||||
return textLine
|
|
||||||
|
|
||||||
def __GetBiologData(self):
|
|
||||||
questCount = min(quest.GetQuestCount(), quest.QUEST_MAX_NUM)
|
|
||||||
for questIndex in range(questCount):
|
|
||||||
(questName, questIcon, questCounterName, questCounterValue) = quest.GetQuestData(questIndex)
|
|
||||||
if not questName.startswith(self.TITLE_PREFIX):
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
|
||||||
stageIndex = int(questName[len(self.TITLE_PREFIX):])
|
|
||||||
except:
|
|
||||||
continue
|
|
||||||
|
|
||||||
totalRequired = self.STAGE_TARGETS.get(stageIndex, questCounterValue)
|
|
||||||
(clockName, clockValue) = quest.GetQuestLastTime(questIndex)
|
|
||||||
return {
|
|
||||||
"stage" : stageIndex,
|
|
||||||
"itemName" : questCounterName,
|
|
||||||
"remaining" : max(questCounterValue, 0),
|
|
||||||
"required" : max(totalRequired, 0),
|
|
||||||
"clockName" : clockName,
|
|
||||||
"clockValue" : max(clockValue, 0),
|
|
||||||
}
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def __FormatCooldown(self, seconds):
|
|
||||||
hours = seconds // 3600
|
|
||||||
minutes = (seconds // 60) % 60
|
|
||||||
return "%02d:%02d:%02d" % (hours, minutes, seconds % 60)
|
|
||||||
|
|
||||||
def __RefreshLockedState(self):
|
|
||||||
if player.GetStatus(player.LEVEL) < 30:
|
|
||||||
self.statusLine.SetText("Status: Unlocks at level 30")
|
|
||||||
else:
|
|
||||||
self.statusLine.SetText("Status: No active biolog stage")
|
|
||||||
|
|
||||||
self.stageLine.SetText("Stage: -")
|
|
||||||
self.itemLine.SetText("Item: -")
|
|
||||||
self.progressLine.SetText("Progress: -")
|
|
||||||
self.cooldownLine.SetText("Cooldown: -")
|
|
||||||
self.submitButton.Hide()
|
|
||||||
|
|
||||||
def Refresh(self):
|
|
||||||
biologData = self.__GetBiologData()
|
|
||||||
if not biologData:
|
|
||||||
self.__RefreshLockedState()
|
|
||||||
return
|
|
||||||
|
|
||||||
submitted = max(biologData["required"] - biologData["remaining"], 0)
|
|
||||||
self.statusLine.SetText("Status: %s" % ("Ready" if biologData["clockValue"] <= 0 else "Cooldown"))
|
|
||||||
self.stageLine.SetText("Stage: %d / 9" % biologData["stage"])
|
|
||||||
self.itemLine.SetText("Item: %s" % biologData["itemName"])
|
|
||||||
self.progressLine.SetText("Progress: %d / %d" % (submitted, biologData["required"]))
|
|
||||||
|
|
||||||
if biologData["clockValue"] > 0 and len(biologData["clockName"]) > 0:
|
|
||||||
self.cooldownLine.SetText("Cooldown: %s" % self.__FormatCooldown(biologData["clockValue"]))
|
|
||||||
else:
|
|
||||||
self.cooldownLine.SetText("Cooldown: Ready")
|
|
||||||
|
|
||||||
self.submitButton.Show()
|
|
||||||
|
|
||||||
def Show(self):
|
|
||||||
self.Refresh()
|
|
||||||
ui.BoardWithTitleBar.Show(self)
|
|
||||||
|
|
||||||
def OnUpdate(self):
|
|
||||||
currentTime = time.time()
|
|
||||||
if currentTime - self.lastRefreshTime < 0.2:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.lastRefreshTime = currentTime
|
|
||||||
self.Refresh()
|
|
||||||
|
|
||||||
def __OnSubmit(self):
|
|
||||||
try:
|
|
||||||
net.SendBiologSubmit()
|
|
||||||
except AttributeError:
|
|
||||||
net.SendChatPacket("/biolog_submit", 0)
|
|
||||||
self.lastRefreshTime = 0.0
|
|
||||||
self.Refresh()
|
|
||||||
@@ -1,233 +0,0 @@
|
|||||||
import item
|
|
||||||
import net
|
|
||||||
import player
|
|
||||||
import ui
|
|
||||||
|
|
||||||
|
|
||||||
STATE_MAX = 3
|
|
||||||
STATE_ACTIVE = 0
|
|
||||||
STATE_CURRENT = 0
|
|
||||||
STATE_SUCCESS = 0
|
|
||||||
STATE_FAIL = 0
|
|
||||||
OPEN_WINDOWS = []
|
|
||||||
|
|
||||||
|
|
||||||
def SetStoneQueueState(maxCount, active, current, success, fail):
|
|
||||||
global STATE_MAX
|
|
||||||
global STATE_ACTIVE
|
|
||||||
global STATE_CURRENT
|
|
||||||
global STATE_SUCCESS
|
|
||||||
global STATE_FAIL
|
|
||||||
|
|
||||||
STATE_MAX = max(1, int(maxCount))
|
|
||||||
STATE_ACTIVE = 1 if int(active) else 0
|
|
||||||
STATE_CURRENT = max(0, int(current))
|
|
||||||
STATE_SUCCESS = max(0, int(success))
|
|
||||||
STATE_FAIL = max(0, int(fail))
|
|
||||||
|
|
||||||
for window in OPEN_WINDOWS:
|
|
||||||
try:
|
|
||||||
window.Refresh()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class StoneQueueWindow(ui.BoardWithTitleBar):
|
|
||||||
PAGE_SIZE = 20
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
ui.BoardWithTitleBar.__init__(self)
|
|
||||||
|
|
||||||
OPEN_WINDOWS.append(self)
|
|
||||||
|
|
||||||
self.scrollSlotPos = -1
|
|
||||||
self.selectedSlots = []
|
|
||||||
self.eligibleSlots = []
|
|
||||||
self.pageIndex = 0
|
|
||||||
self.candidateButtons = []
|
|
||||||
self.queueLines = []
|
|
||||||
|
|
||||||
self.AddFlag("float")
|
|
||||||
self.AddFlag("movable")
|
|
||||||
self.SetSize(340, 355)
|
|
||||||
self.SetTitleName("Stone Queue")
|
|
||||||
self.SetCloseEvent(self.Hide)
|
|
||||||
|
|
||||||
self.__CreateChildren()
|
|
||||||
self.Hide()
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
if self in OPEN_WINDOWS:
|
|
||||||
OPEN_WINDOWS.remove(self)
|
|
||||||
ui.BoardWithTitleBar.__del__(self)
|
|
||||||
|
|
||||||
def Destroy(self):
|
|
||||||
if self in OPEN_WINDOWS:
|
|
||||||
OPEN_WINDOWS.remove(self)
|
|
||||||
self.ClearDictionary()
|
|
||||||
self.selectedSlots = []
|
|
||||||
self.eligibleSlots = []
|
|
||||||
self.candidateButtons = []
|
|
||||||
self.queueLines = []
|
|
||||||
|
|
||||||
def __CreateChildren(self):
|
|
||||||
self.scrollLine = self.__CreateLine(15, 36)
|
|
||||||
self.statusLine = self.__CreateLine(15, 56)
|
|
||||||
self.progressLine = self.__CreateLine(15, 76)
|
|
||||||
self.resultLine = self.__CreateLine(15, 96)
|
|
||||||
|
|
||||||
self.prevButton = self.__CreateButton(15, 118, 45, "Prev")
|
|
||||||
self.prevButton.SetEvent(self.__ChangePage, -1)
|
|
||||||
self.pageLine = self.__CreateLine(127, 122)
|
|
||||||
self.nextButton = self.__CreateButton(280, 118, 45, "Next")
|
|
||||||
self.nextButton.SetEvent(self.__ChangePage, 1)
|
|
||||||
|
|
||||||
for row in range(5):
|
|
||||||
for column in range(4):
|
|
||||||
button = self.__CreateButton(15 + column * 78, 145 + row * 24, 72, "-")
|
|
||||||
self.candidateButtons.append(button)
|
|
||||||
|
|
||||||
for index in range(8):
|
|
||||||
line = self.__CreateLine(15, 272 + index * 10)
|
|
||||||
self.queueLines.append(line)
|
|
||||||
|
|
||||||
self.startButton = self.__CreateButton(185, 328, 65, "Start")
|
|
||||||
self.startButton.SetEvent(self.__StartQueue)
|
|
||||||
self.cancelButton = self.__CreateButton(260, 328, 65, "Cancel")
|
|
||||||
self.cancelButton.SetEvent(self.__CancelQueue)
|
|
||||||
|
|
||||||
def __CreateLine(self, x, y):
|
|
||||||
textLine = ui.TextLine()
|
|
||||||
textLine.SetParent(self)
|
|
||||||
textLine.SetPosition(x, y)
|
|
||||||
textLine.SetOutline()
|
|
||||||
textLine.Show()
|
|
||||||
return textLine
|
|
||||||
|
|
||||||
def __CreateButton(self, x, y, width, text):
|
|
||||||
button = ui.Button()
|
|
||||||
button.SetParent(self)
|
|
||||||
button.SetPosition(x, y)
|
|
||||||
button.SetUpVisual("d:/ymir work/ui/public/small_thin_button_01.sub")
|
|
||||||
button.SetOverVisual("d:/ymir work/ui/public/small_thin_button_02.sub")
|
|
||||||
button.SetDownVisual("d:/ymir work/ui/public/small_thin_button_03.sub")
|
|
||||||
button.SetDisableVisual("d:/ymir work/ui/public/small_thin_button_01.sub")
|
|
||||||
button.SetSize(width, 17)
|
|
||||||
button.SetText(text)
|
|
||||||
button.Show()
|
|
||||||
return button
|
|
||||||
|
|
||||||
def __BuildEligibleSlots(self):
|
|
||||||
self.eligibleSlots = []
|
|
||||||
if self.scrollSlotPos < 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
scrollIndex = player.GetItemIndex(self.scrollSlotPos)
|
|
||||||
for slot in range(player.INVENTORY_PAGE_SIZE * player.INVENTORY_PAGE_COUNT):
|
|
||||||
if player.REFINE_OK != player.CanRefine(scrollIndex, slot):
|
|
||||||
continue
|
|
||||||
|
|
||||||
targetIndex = player.GetItemIndex(slot)
|
|
||||||
if targetIndex == 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
item.SelectItem(targetIndex)
|
|
||||||
if item.GetItemType() != item.ITEM_TYPE_METIN:
|
|
||||||
continue
|
|
||||||
|
|
||||||
self.eligibleSlots.append(slot)
|
|
||||||
|
|
||||||
def __GetSlotLabel(self, slot):
|
|
||||||
itemVnum = player.GetItemIndex(slot)
|
|
||||||
if itemVnum == 0:
|
|
||||||
return "Slot %d" % slot
|
|
||||||
|
|
||||||
item.SelectItem(itemVnum)
|
|
||||||
return "%d:+%d" % (slot, player.GetItemGrade(slot))
|
|
||||||
|
|
||||||
def __RefreshCandidates(self):
|
|
||||||
start = self.pageIndex * self.PAGE_SIZE
|
|
||||||
end = start + self.PAGE_SIZE
|
|
||||||
pageSlots = self.eligibleSlots[start:end]
|
|
||||||
|
|
||||||
totalPages = max(1, (len(self.eligibleSlots) + self.PAGE_SIZE - 1) // self.PAGE_SIZE)
|
|
||||||
self.pageLine.SetText("Page %d / %d" % (self.pageIndex + 1, totalPages))
|
|
||||||
|
|
||||||
for index, button in enumerate(self.candidateButtons):
|
|
||||||
if index < len(pageSlots):
|
|
||||||
slot = pageSlots[index]
|
|
||||||
prefix = "[x]" if slot in self.selectedSlots else "[ ]"
|
|
||||||
button.SetText("%s %s" % (prefix, self.__GetSlotLabel(slot)))
|
|
||||||
button.Enable()
|
|
||||||
button.SetEvent(self.__ToggleSlot, slot)
|
|
||||||
else:
|
|
||||||
button.SetText("-")
|
|
||||||
button.Disable()
|
|
||||||
|
|
||||||
self.prevButton.Enable() if self.pageIndex > 0 else self.prevButton.Disable()
|
|
||||||
self.nextButton.Enable() if end < len(self.eligibleSlots) else self.nextButton.Disable()
|
|
||||||
|
|
||||||
def __RefreshQueueLines(self):
|
|
||||||
for index, line in enumerate(self.queueLines):
|
|
||||||
if index < len(self.selectedSlots):
|
|
||||||
line.SetText("Queue %d: %s" % (index + 1, self.__GetSlotLabel(self.selectedSlots[index])))
|
|
||||||
else:
|
|
||||||
line.SetText("Queue %d: -" % (index + 1))
|
|
||||||
|
|
||||||
def __ToggleSlot(self, slot):
|
|
||||||
if STATE_ACTIVE:
|
|
||||||
return
|
|
||||||
|
|
||||||
if slot in self.selectedSlots:
|
|
||||||
self.selectedSlots.remove(slot)
|
|
||||||
elif len(self.selectedSlots) < STATE_MAX:
|
|
||||||
self.selectedSlots.append(slot)
|
|
||||||
|
|
||||||
self.Refresh()
|
|
||||||
|
|
||||||
def __ChangePage(self, delta):
|
|
||||||
totalPages = max(1, (len(self.eligibleSlots) + self.PAGE_SIZE - 1) // self.PAGE_SIZE)
|
|
||||||
self.pageIndex = max(0, min(totalPages - 1, self.pageIndex + delta))
|
|
||||||
self.__RefreshCandidates()
|
|
||||||
|
|
||||||
def __StartQueue(self):
|
|
||||||
if STATE_ACTIVE or self.scrollSlotPos < 0 or not self.selectedSlots:
|
|
||||||
return
|
|
||||||
|
|
||||||
command = "/stone_queue start %d %s" % (
|
|
||||||
self.scrollSlotPos,
|
|
||||||
" ".join([str(slot) for slot in self.selectedSlots[:STATE_MAX]]),
|
|
||||||
)
|
|
||||||
net.SendChatPacket(command, 0)
|
|
||||||
|
|
||||||
def __CancelQueue(self):
|
|
||||||
net.SendChatPacket("/stone_queue cancel", 0)
|
|
||||||
|
|
||||||
def Open(self, scrollSlotPos, targetSlotPos):
|
|
||||||
self.scrollSlotPos = scrollSlotPos
|
|
||||||
self.pageIndex = 0
|
|
||||||
self.selectedSlots = []
|
|
||||||
|
|
||||||
self.__BuildEligibleSlots()
|
|
||||||
if targetSlotPos in self.eligibleSlots:
|
|
||||||
self.selectedSlots.append(targetSlotPos)
|
|
||||||
|
|
||||||
net.SendChatPacket("/stone_queue sync", 0)
|
|
||||||
self.Refresh()
|
|
||||||
self.SetTop()
|
|
||||||
self.Show()
|
|
||||||
|
|
||||||
def Refresh(self):
|
|
||||||
self.scrollLine.SetText("Scroll slot: %d" % self.scrollSlotPos)
|
|
||||||
self.statusLine.SetText("Status: %s" % ("Running" if STATE_ACTIVE else "Ready"))
|
|
||||||
self.progressLine.SetText("Progress: %d / %d" % (STATE_CURRENT, len(self.selectedSlots)))
|
|
||||||
self.resultLine.SetText("Results: %d success / %d fail / max %d" % (STATE_SUCCESS, STATE_FAIL, STATE_MAX))
|
|
||||||
self.__RefreshCandidates()
|
|
||||||
self.__RefreshQueueLines()
|
|
||||||
|
|
||||||
if STATE_ACTIVE:
|
|
||||||
self.startButton.Disable()
|
|
||||||
self.cancelButton.Enable()
|
|
||||||
else:
|
|
||||||
self.startButton.Enable()
|
|
||||||
self.cancelButton.Disable()
|
|
||||||
@@ -1,455 +0,0 @@
|
|||||||
import item
|
|
||||||
import net
|
|
||||||
import player
|
|
||||||
import ui
|
|
||||||
import uitooltip
|
|
||||||
|
|
||||||
|
|
||||||
STATE_SPEED = 1
|
|
||||||
STATE_ACTIVE_COUNT = 0
|
|
||||||
STATE_SCROLL_COUNT = 0
|
|
||||||
STATE_ETA_SECONDS = 0
|
|
||||||
STATE_SLOTS = []
|
|
||||||
OPEN_WINDOWS = []
|
|
||||||
_AFFECT_HELPER = None
|
|
||||||
|
|
||||||
for _slotIndex in range(5):
|
|
||||||
STATE_SLOTS.append({
|
|
||||||
"active": 0,
|
|
||||||
"itemCell": 0,
|
|
||||||
"attrType": 0,
|
|
||||||
"minValue": 0,
|
|
||||||
"attempts": 0,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
def _GetAffectHelper():
|
|
||||||
global _AFFECT_HELPER
|
|
||||||
|
|
||||||
if _AFFECT_HELPER is None:
|
|
||||||
_AFFECT_HELPER = uitooltip.ItemToolTip()
|
|
||||||
|
|
||||||
return _AFFECT_HELPER
|
|
||||||
|
|
||||||
|
|
||||||
def _GetAffectLabel(attrType):
|
|
||||||
if attrType <= 0:
|
|
||||||
return "-"
|
|
||||||
|
|
||||||
try:
|
|
||||||
label = _GetAffectHelper()._ItemToolTip__GetAffectString(attrType, 1)
|
|
||||||
except:
|
|
||||||
label = None
|
|
||||||
|
|
||||||
if not label:
|
|
||||||
return "Attr %d" % attrType
|
|
||||||
|
|
||||||
return label
|
|
||||||
|
|
||||||
|
|
||||||
ATTR_OPTIONS = (
|
|
||||||
(item.APPLY_MAX_HP, _GetAffectLabel(item.APPLY_MAX_HP)),
|
|
||||||
(item.APPLY_MAX_SP, _GetAffectLabel(item.APPLY_MAX_SP)),
|
|
||||||
(item.APPLY_STR, _GetAffectLabel(item.APPLY_STR)),
|
|
||||||
(item.APPLY_DEX, _GetAffectLabel(item.APPLY_DEX)),
|
|
||||||
(item.APPLY_CON, _GetAffectLabel(item.APPLY_CON)),
|
|
||||||
(item.APPLY_INT, _GetAffectLabel(item.APPLY_INT)),
|
|
||||||
(item.APPLY_ATT_SPEED, _GetAffectLabel(item.APPLY_ATT_SPEED)),
|
|
||||||
(item.APPLY_MOV_SPEED, _GetAffectLabel(item.APPLY_MOV_SPEED)),
|
|
||||||
(item.APPLY_CAST_SPEED, _GetAffectLabel(item.APPLY_CAST_SPEED)),
|
|
||||||
(item.APPLY_CRITICAL_PCT, _GetAffectLabel(item.APPLY_CRITICAL_PCT)),
|
|
||||||
(item.APPLY_PENETRATE_PCT, _GetAffectLabel(item.APPLY_PENETRATE_PCT)),
|
|
||||||
(item.APPLY_ATTBONUS_MONSTER, _GetAffectLabel(item.APPLY_ATTBONUS_MONSTER)),
|
|
||||||
(item.APPLY_ATTBONUS_DEVIL, _GetAffectLabel(item.APPLY_ATTBONUS_DEVIL)),
|
|
||||||
(item.APPLY_ATTBONUS_HUMAN, _GetAffectLabel(item.APPLY_ATTBONUS_HUMAN)),
|
|
||||||
(item.APPLY_STEAL_HP, _GetAffectLabel(item.APPLY_STEAL_HP)),
|
|
||||||
(item.APPLY_STEAL_SP, _GetAffectLabel(item.APPLY_STEAL_SP)),
|
|
||||||
(item.APPLY_BLOCK, _GetAffectLabel(item.APPLY_BLOCK)),
|
|
||||||
(item.APPLY_DODGE, _GetAffectLabel(item.APPLY_DODGE)),
|
|
||||||
(item.APPLY_ATT_GRADE_BONUS, _GetAffectLabel(item.APPLY_ATT_GRADE_BONUS)),
|
|
||||||
(item.APPLY_DEF_GRADE_BONUS, _GetAffectLabel(item.APPLY_DEF_GRADE_BONUS)),
|
|
||||||
(item.APPLY_RESIST_SWORD, _GetAffectLabel(item.APPLY_RESIST_SWORD)),
|
|
||||||
(item.APPLY_RESIST_TWOHAND, _GetAffectLabel(item.APPLY_RESIST_TWOHAND)),
|
|
||||||
(item.APPLY_RESIST_DAGGER, _GetAffectLabel(item.APPLY_RESIST_DAGGER)),
|
|
||||||
(item.APPLY_RESIST_BOW, _GetAffectLabel(item.APPLY_RESIST_BOW)),
|
|
||||||
(item.APPLY_RESIST_FIRE, _GetAffectLabel(item.APPLY_RESIST_FIRE)),
|
|
||||||
(item.APPLY_RESIST_ELEC, _GetAffectLabel(item.APPLY_RESIST_ELEC)),
|
|
||||||
(item.APPLY_RESIST_MAGIC, _GetAffectLabel(item.APPLY_RESIST_MAGIC)),
|
|
||||||
(item.APPLY_RESIST_WIND, _GetAffectLabel(item.APPLY_RESIST_WIND)),
|
|
||||||
(item.APPLY_RESIST_ICE, _GetAffectLabel(item.APPLY_RESIST_ICE)),
|
|
||||||
(item.APPLY_RESIST_EARTH, _GetAffectLabel(item.APPLY_RESIST_EARTH)),
|
|
||||||
(item.APPLY_RESIST_DARK, _GetAffectLabel(item.APPLY_RESIST_DARK)),
|
|
||||||
)
|
|
||||||
|
|
||||||
SPEED_OPTIONS = (
|
|
||||||
(0, "Slow / 3s"),
|
|
||||||
(1, "Normal / 2s"),
|
|
||||||
(2, "Fast / 1s"),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def SetSwitchbotState(speedIndex, activeCount, scrollCount, etaSeconds):
|
|
||||||
global STATE_SPEED
|
|
||||||
global STATE_ACTIVE_COUNT
|
|
||||||
global STATE_SCROLL_COUNT
|
|
||||||
global STATE_ETA_SECONDS
|
|
||||||
|
|
||||||
STATE_SPEED = int(speedIndex)
|
|
||||||
STATE_ACTIVE_COUNT = max(0, int(activeCount))
|
|
||||||
STATE_SCROLL_COUNT = max(0, int(scrollCount))
|
|
||||||
STATE_ETA_SECONDS = max(0, int(etaSeconds))
|
|
||||||
|
|
||||||
for window in OPEN_WINDOWS:
|
|
||||||
try:
|
|
||||||
window.Refresh()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def SetSwitchbotSlotState(slotIndex, active, itemCell, attrType, minValue, attempts):
|
|
||||||
slotIndex = int(slotIndex)
|
|
||||||
if slotIndex < 0 or slotIndex >= len(STATE_SLOTS):
|
|
||||||
return
|
|
||||||
|
|
||||||
STATE_SLOTS[slotIndex]["active"] = 1 if int(active) else 0
|
|
||||||
STATE_SLOTS[slotIndex]["itemCell"] = int(itemCell)
|
|
||||||
STATE_SLOTS[slotIndex]["attrType"] = int(attrType)
|
|
||||||
STATE_SLOTS[slotIndex]["minValue"] = int(minValue)
|
|
||||||
STATE_SLOTS[slotIndex]["attempts"] = int(attempts)
|
|
||||||
|
|
||||||
for window in OPEN_WINDOWS:
|
|
||||||
try:
|
|
||||||
window.Refresh()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class SwitchbotWindow(ui.BoardWithTitleBar):
|
|
||||||
CANDIDATE_PAGE_SIZE = 12
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
ui.BoardWithTitleBar.__init__(self)
|
|
||||||
|
|
||||||
OPEN_WINDOWS.append(self)
|
|
||||||
|
|
||||||
self.selectedSlotIndex = 0
|
|
||||||
self.pageIndex = 0
|
|
||||||
self.candidateSlots = []
|
|
||||||
self.slotWidgets = []
|
|
||||||
self.candidateButtons = []
|
|
||||||
self.speedLabels = {}
|
|
||||||
self.attrLabels = {}
|
|
||||||
|
|
||||||
self.AddFlag("float")
|
|
||||||
self.AddFlag("movable")
|
|
||||||
self.SetSize(535, 406)
|
|
||||||
self.SetTitleName("Switchbot")
|
|
||||||
self.SetCloseEvent(self.Hide)
|
|
||||||
|
|
||||||
self.__CreateChildren()
|
|
||||||
self.Hide()
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
if self in OPEN_WINDOWS:
|
|
||||||
OPEN_WINDOWS.remove(self)
|
|
||||||
ui.BoardWithTitleBar.__del__(self)
|
|
||||||
|
|
||||||
def Destroy(self):
|
|
||||||
if self in OPEN_WINDOWS:
|
|
||||||
OPEN_WINDOWS.remove(self)
|
|
||||||
self.ClearDictionary()
|
|
||||||
self.slotWidgets = []
|
|
||||||
self.candidateButtons = []
|
|
||||||
self.candidateSlots = []
|
|
||||||
self.speedLabels = {}
|
|
||||||
self.attrLabels = {}
|
|
||||||
|
|
||||||
def __CreateChildren(self):
|
|
||||||
self.statusLine = self.__CreateLine(15, 36)
|
|
||||||
self.scrollLine = self.__CreateLine(15, 56)
|
|
||||||
self.etaLine = self.__CreateLine(15, 76)
|
|
||||||
self.helpLine = self.__CreateLine(15, 96)
|
|
||||||
|
|
||||||
self.speedCombo = ui.ComboBox()
|
|
||||||
self.speedCombo.SetParent(self)
|
|
||||||
self.speedCombo.SetPosition(398, 34)
|
|
||||||
self.speedCombo.SetSize(120, 18)
|
|
||||||
self.speedCombo.SetEvent(self.__OnChangeSpeed)
|
|
||||||
self.speedCombo.Show()
|
|
||||||
|
|
||||||
for (speedIndex, label) in SPEED_OPTIONS:
|
|
||||||
self.speedCombo.InsertItem(speedIndex, label)
|
|
||||||
self.speedLabels[speedIndex] = label
|
|
||||||
|
|
||||||
for slotIndex in range(5):
|
|
||||||
baseY = 126 + slotIndex * 38
|
|
||||||
row = {}
|
|
||||||
|
|
||||||
row["selectButton"] = self.__CreateButton(15, baseY, 48, "Slot %d" % (slotIndex + 1))
|
|
||||||
row["selectButton"].SetEvent(self.__SelectSlot, slotIndex)
|
|
||||||
|
|
||||||
row["itemLine"] = self.__CreateLine(72, baseY + 2)
|
|
||||||
row["statusLine"] = self.__CreateLine(72, baseY + 18)
|
|
||||||
|
|
||||||
row["attrCombo"] = ui.ComboBox()
|
|
||||||
row["attrCombo"].SetParent(self)
|
|
||||||
row["attrCombo"].SetPosition(220, baseY)
|
|
||||||
row["attrCombo"].SetSize(165, 18)
|
|
||||||
row["attrCombo"].SetEvent(lambda attrType, line=slotIndex: self.__SetAttrType(line, attrType))
|
|
||||||
row["attrCombo"].Show()
|
|
||||||
|
|
||||||
for (attrType, label) in ATTR_OPTIONS:
|
|
||||||
row["attrCombo"].InsertItem(attrType, label)
|
|
||||||
|
|
||||||
attrBar = ui.SlotBar()
|
|
||||||
attrBar.SetParent(self)
|
|
||||||
attrBar.SetPosition(392, baseY)
|
|
||||||
attrBar.SetSize(48, 18)
|
|
||||||
attrBar.Show()
|
|
||||||
|
|
||||||
row["valueBar"] = attrBar
|
|
||||||
row["valueEdit"] = ui.EditLine()
|
|
||||||
row["valueEdit"].SetParent(attrBar)
|
|
||||||
row["valueEdit"].SetPosition(3, 3)
|
|
||||||
row["valueEdit"].SetSize(42, 12)
|
|
||||||
row["valueEdit"].SetMax(5)
|
|
||||||
row["valueEdit"].SetNumberMode()
|
|
||||||
row["valueEdit"].Show()
|
|
||||||
|
|
||||||
row["startButton"] = self.__CreateButton(447, baseY, 40, "Start")
|
|
||||||
row["startButton"].SetEvent(self.__ToggleSlot, slotIndex)
|
|
||||||
row["clearButton"] = self.__CreateButton(492, baseY, 28, "X")
|
|
||||||
row["clearButton"].SetEvent(self.__ClearSlot, slotIndex)
|
|
||||||
|
|
||||||
self.slotWidgets.append(row)
|
|
||||||
|
|
||||||
self.prevButton = self.__CreateButton(15, 330, 44, "Prev")
|
|
||||||
self.prevButton.SetEvent(self.__ChangePage, -1)
|
|
||||||
self.pageLine = self.__CreateLine(80, 334)
|
|
||||||
self.nextButton = self.__CreateButton(170, 330, 44, "Next")
|
|
||||||
self.nextButton.SetEvent(self.__ChangePage, 1)
|
|
||||||
|
|
||||||
for index in range(self.CANDIDATE_PAGE_SIZE):
|
|
||||||
column = index % 2
|
|
||||||
row = index // 2
|
|
||||||
button = self.__CreateButton(15 + column * 155, 356 + row * 18, 148, "-")
|
|
||||||
button.SetEvent(self.__AssignCandidate, index)
|
|
||||||
self.candidateButtons.append(button)
|
|
||||||
|
|
||||||
self.syncButton = self.__CreateButton(305, 330, 54, "Sync")
|
|
||||||
self.syncButton.SetEvent(self.__Sync)
|
|
||||||
self.startAllButton = self.__CreateButton(366, 330, 74, "Start All")
|
|
||||||
self.startAllButton.SetEvent(self.__StartAll)
|
|
||||||
self.stopAllButton = self.__CreateButton(446, 330, 74, "Stop All")
|
|
||||||
self.stopAllButton.SetEvent(self.__StopAll)
|
|
||||||
|
|
||||||
def __CreateLine(self, x, y):
|
|
||||||
textLine = ui.TextLine()
|
|
||||||
textLine.SetParent(self)
|
|
||||||
textLine.SetPosition(x, y)
|
|
||||||
textLine.SetOutline()
|
|
||||||
textLine.Show()
|
|
||||||
return textLine
|
|
||||||
|
|
||||||
def __CreateButton(self, x, y, width, text):
|
|
||||||
button = ui.Button()
|
|
||||||
button.SetParent(self)
|
|
||||||
button.SetPosition(x, y)
|
|
||||||
button.SetUpVisual("d:/ymir work/ui/public/small_thin_button_01.sub")
|
|
||||||
button.SetOverVisual("d:/ymir work/ui/public/small_thin_button_02.sub")
|
|
||||||
button.SetDownVisual("d:/ymir work/ui/public/small_thin_button_03.sub")
|
|
||||||
button.SetDisableVisual("d:/ymir work/ui/public/small_thin_button_01.sub")
|
|
||||||
button.SetSize(width, 17)
|
|
||||||
button.SetText(text)
|
|
||||||
button.Show()
|
|
||||||
return button
|
|
||||||
|
|
||||||
def __Send(self, command):
|
|
||||||
net.SendChatPacket(command, 0)
|
|
||||||
|
|
||||||
def __IsEligibleItem(self, slotPos):
|
|
||||||
itemVnum = player.GetItemIndex(slotPos)
|
|
||||||
if itemVnum == 0:
|
|
||||||
return False
|
|
||||||
|
|
||||||
item.SelectItem(itemVnum)
|
|
||||||
if item.GetItemType() == item.ITEM_TYPE_COSTUME:
|
|
||||||
return False
|
|
||||||
|
|
||||||
if item.GetItemType() not in (item.ITEM_TYPE_WEAPON, item.ITEM_TYPE_ARMOR):
|
|
||||||
return False
|
|
||||||
|
|
||||||
for attrIndex in range(player.ATTRIBUTE_SLOT_MAX_NUM):
|
|
||||||
if player.GetItemAttribute(slotPos, attrIndex)[0] != 0:
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
def __GetItemLabel(self, slotPos):
|
|
||||||
itemVnum = player.GetItemIndex(slotPos)
|
|
||||||
if itemVnum == 0:
|
|
||||||
return "Slot %d" % slotPos
|
|
||||||
|
|
||||||
item.SelectItem(itemVnum)
|
|
||||||
return "%d: %s" % (slotPos, item.GetItemName())
|
|
||||||
|
|
||||||
def __BuildCandidateSlots(self):
|
|
||||||
self.candidateSlots = []
|
|
||||||
|
|
||||||
for slotPos in range(player.INVENTORY_PAGE_SIZE * player.INVENTORY_PAGE_COUNT):
|
|
||||||
if self.__IsEligibleItem(slotPos):
|
|
||||||
self.candidateSlots.append(slotPos)
|
|
||||||
|
|
||||||
def __FormatEta(self):
|
|
||||||
if STATE_ETA_SECONDS <= 0:
|
|
||||||
return "ETA: -"
|
|
||||||
|
|
||||||
minutes = STATE_ETA_SECONDS // 60
|
|
||||||
seconds = STATE_ETA_SECONDS % 60
|
|
||||||
return "ETA: %02d:%02d" % (minutes, seconds)
|
|
||||||
|
|
||||||
def __GetAttrType(self, slotIndex):
|
|
||||||
return STATE_SLOTS[slotIndex]["attrType"]
|
|
||||||
|
|
||||||
def __GetMinValue(self, slotIndex):
|
|
||||||
text = self.slotWidgets[slotIndex]["valueEdit"].GetText()
|
|
||||||
if not text:
|
|
||||||
return STATE_SLOTS[slotIndex]["minValue"]
|
|
||||||
return int(text)
|
|
||||||
|
|
||||||
def __SelectSlot(self, slotIndex):
|
|
||||||
self.selectedSlotIndex = slotIndex
|
|
||||||
self.Refresh()
|
|
||||||
|
|
||||||
def __SetAttrType(self, slotIndex, attrType):
|
|
||||||
SetSwitchbotSlotState(
|
|
||||||
slotIndex,
|
|
||||||
STATE_SLOTS[slotIndex]["active"],
|
|
||||||
STATE_SLOTS[slotIndex]["itemCell"],
|
|
||||||
attrType,
|
|
||||||
STATE_SLOTS[slotIndex]["minValue"],
|
|
||||||
STATE_SLOTS[slotIndex]["attempts"],
|
|
||||||
)
|
|
||||||
|
|
||||||
def __AssignCandidate(self, localIndex):
|
|
||||||
candidateIndex = self.pageIndex * self.CANDIDATE_PAGE_SIZE + localIndex
|
|
||||||
if candidateIndex < 0 or candidateIndex >= len(self.candidateSlots):
|
|
||||||
return
|
|
||||||
|
|
||||||
slotIndex = self.selectedSlotIndex
|
|
||||||
SetSwitchbotSlotState(
|
|
||||||
slotIndex,
|
|
||||||
0,
|
|
||||||
self.candidateSlots[candidateIndex],
|
|
||||||
STATE_SLOTS[slotIndex]["attrType"],
|
|
||||||
STATE_SLOTS[slotIndex]["minValue"],
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
|
|
||||||
def __ToggleSlot(self, slotIndex):
|
|
||||||
slotState = STATE_SLOTS[slotIndex]
|
|
||||||
if slotState["active"]:
|
|
||||||
self.__Send("/switchbot stop %d" % slotIndex)
|
|
||||||
return
|
|
||||||
|
|
||||||
itemCell = slotState["itemCell"]
|
|
||||||
attrType = self.__GetAttrType(slotIndex)
|
|
||||||
minValue = self.__GetMinValue(slotIndex)
|
|
||||||
if not self.__IsEligibleItem(itemCell) or attrType <= 0 or minValue <= 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
SetSwitchbotSlotState(slotIndex, 0, itemCell, attrType, minValue, slotState["attempts"])
|
|
||||||
self.__Send("/switchbot start %d %d %d %d" % (slotIndex, itemCell, attrType, minValue))
|
|
||||||
|
|
||||||
def __ClearSlot(self, slotIndex):
|
|
||||||
self.__Send("/switchbot clear %d" % slotIndex)
|
|
||||||
|
|
||||||
def __ChangePage(self, delta):
|
|
||||||
totalPages = max(1, (len(self.candidateSlots) + self.CANDIDATE_PAGE_SIZE - 1) // self.CANDIDATE_PAGE_SIZE)
|
|
||||||
self.pageIndex = max(0, min(totalPages - 1, self.pageIndex + delta))
|
|
||||||
self.Refresh()
|
|
||||||
|
|
||||||
def __OnChangeSpeed(self, speedIndex):
|
|
||||||
self.__Send("/switchbot speed %d" % int(speedIndex))
|
|
||||||
|
|
||||||
def __Sync(self):
|
|
||||||
self.__Send("/switchbot sync")
|
|
||||||
|
|
||||||
def __StartAll(self):
|
|
||||||
for slotIndex in range(len(STATE_SLOTS)):
|
|
||||||
slotState = STATE_SLOTS[slotIndex]
|
|
||||||
if slotState["active"]:
|
|
||||||
continue
|
|
||||||
|
|
||||||
itemCell = slotState["itemCell"]
|
|
||||||
attrType = self.__GetAttrType(slotIndex)
|
|
||||||
minValue = self.__GetMinValue(slotIndex)
|
|
||||||
if not self.__IsEligibleItem(itemCell) or attrType <= 0 or minValue <= 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
self.__Send("/switchbot start %d %d %d %d" % (slotIndex, itemCell, attrType, minValue))
|
|
||||||
|
|
||||||
def __StopAll(self):
|
|
||||||
self.__Send("/switchbot stop_all")
|
|
||||||
|
|
||||||
def Refresh(self):
|
|
||||||
self.__BuildCandidateSlots()
|
|
||||||
|
|
||||||
self.statusLine.SetText("Status: %d active slot(s)" % STATE_ACTIVE_COUNT)
|
|
||||||
self.scrollLine.SetText("Switch items: %d" % STATE_SCROLL_COUNT)
|
|
||||||
self.etaLine.SetText(self.__FormatEta())
|
|
||||||
self.helpLine.SetText("Select a row, assign an item, pick a target bonus and min value")
|
|
||||||
self.speedCombo.SetCurrentItem(self.speedLabels.get(STATE_SPEED, SPEED_OPTIONS[1][1]))
|
|
||||||
|
|
||||||
for slotIndex in range(len(self.slotWidgets)):
|
|
||||||
slotState = STATE_SLOTS[slotIndex]
|
|
||||||
row = self.slotWidgets[slotIndex]
|
|
||||||
row["selectButton"].SetText(("> " if self.selectedSlotIndex == slotIndex else "") + "S%d" % (slotIndex + 1))
|
|
||||||
row["itemLine"].SetText("Item: %s" % ("-" if not self.__IsEligibleItem(slotState["itemCell"]) else self.__GetItemLabel(slotState["itemCell"])))
|
|
||||||
row["statusLine"].SetText("Target: %s / tries %d / %s" % (
|
|
||||||
_GetAffectLabel(slotState["attrType"]),
|
|
||||||
slotState["attempts"],
|
|
||||||
"Running" if slotState["active"] else "Ready",
|
|
||||||
))
|
|
||||||
|
|
||||||
if slotState["attrType"] > 0:
|
|
||||||
row["attrCombo"].SetCurrentItem(_GetAffectLabel(slotState["attrType"]))
|
|
||||||
else:
|
|
||||||
row["attrCombo"].SetCurrentItem("-")
|
|
||||||
|
|
||||||
if slotState["minValue"] > 0 and row["valueEdit"].GetText() != str(slotState["minValue"]):
|
|
||||||
row["valueEdit"].SetText(str(slotState["minValue"]))
|
|
||||||
elif slotState["minValue"] <= 0 and row["valueEdit"].GetText():
|
|
||||||
row["valueEdit"].SetText("")
|
|
||||||
|
|
||||||
row["startButton"].SetText("Stop" if slotState["active"] else "Start")
|
|
||||||
|
|
||||||
start = self.pageIndex * self.CANDIDATE_PAGE_SIZE
|
|
||||||
end = start + self.CANDIDATE_PAGE_SIZE
|
|
||||||
pageSlots = self.candidateSlots[start:end]
|
|
||||||
totalPages = max(1, (len(self.candidateSlots) + self.CANDIDATE_PAGE_SIZE - 1) // self.CANDIDATE_PAGE_SIZE)
|
|
||||||
self.pageLine.SetText("Candidates %d / %d" % (self.pageIndex + 1, totalPages))
|
|
||||||
|
|
||||||
for localIndex in range(len(self.candidateButtons)):
|
|
||||||
button = self.candidateButtons[localIndex]
|
|
||||||
if localIndex < len(pageSlots):
|
|
||||||
button.SetText(self.__GetItemLabel(pageSlots[localIndex]))
|
|
||||||
button.Enable()
|
|
||||||
else:
|
|
||||||
button.SetText("-")
|
|
||||||
button.Disable()
|
|
||||||
|
|
||||||
if self.pageIndex > 0:
|
|
||||||
self.prevButton.Enable()
|
|
||||||
else:
|
|
||||||
self.prevButton.Disable()
|
|
||||||
|
|
||||||
if end < len(self.candidateSlots):
|
|
||||||
self.nextButton.Enable()
|
|
||||||
else:
|
|
||||||
self.nextButton.Disable()
|
|
||||||
|
|
||||||
def Show(self):
|
|
||||||
self.__Sync()
|
|
||||||
self.Refresh()
|
|
||||||
ui.BoardWithTitleBar.Show(self)
|
|
||||||
@@ -1,173 +0,0 @@
|
|||||||
import time
|
|
||||||
|
|
||||||
import background
|
|
||||||
import net
|
|
||||||
import player
|
|
||||||
import quest
|
|
||||||
import ui
|
|
||||||
|
|
||||||
|
|
||||||
class TeleportWindow(ui.BoardWithTitleBar):
|
|
||||||
TITLE = "Teleport System"
|
|
||||||
PRESET_BUTTONS = (
|
|
||||||
(1, "Village 1"),
|
|
||||||
(2, "Village 2"),
|
|
||||||
(3, "Valley"),
|
|
||||||
(4, "Desert"),
|
|
||||||
(5, "Sohan"),
|
|
||||||
(6, "Fireland"),
|
|
||||||
(7, "Devil"),
|
|
||||||
(8, "Cave"),
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
ui.BoardWithTitleBar.__init__(self)
|
|
||||||
|
|
||||||
self.lastRefreshTime = 0.0
|
|
||||||
self.slotRows = []
|
|
||||||
|
|
||||||
self.AddFlag("float")
|
|
||||||
self.AddFlag("movable")
|
|
||||||
self.SetSize(310, 255)
|
|
||||||
self.SetTitleName("Teleport")
|
|
||||||
self.SetCloseEvent(self.Hide)
|
|
||||||
|
|
||||||
self.__CreateChildren()
|
|
||||||
self.Hide()
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
ui.BoardWithTitleBar.__del__(self)
|
|
||||||
|
|
||||||
def __CreateChildren(self):
|
|
||||||
self.statusLine = self.__CreateValueLine(15, 36)
|
|
||||||
self.mapLine = self.__CreateValueLine(15, 56)
|
|
||||||
self.coordLine = self.__CreateValueLine(15, 76)
|
|
||||||
self.slotSummaryLine = self.__CreateValueLine(15, 96)
|
|
||||||
self.cooldownLine = self.__CreateValueLine(15, 116)
|
|
||||||
|
|
||||||
for index, presetData in enumerate(self.PRESET_BUTTONS):
|
|
||||||
(presetId, label) = presetData
|
|
||||||
row = index // 4
|
|
||||||
column = index % 4
|
|
||||||
|
|
||||||
button = self.__CreateButton(15 + column * 71, 142 + row * 24, 64, label)
|
|
||||||
button.SetEvent(self.__SendPresetWarp, presetId)
|
|
||||||
|
|
||||||
for slot in range(1, 6):
|
|
||||||
label = self.__CreateValueLine(15, 196 + (slot - 1) * 11)
|
|
||||||
saveButton = self.__CreateButton(100, 192 + (slot - 1) * 11, 42, "Save")
|
|
||||||
saveButton.SetEvent(self.__SendSaveSlot, slot)
|
|
||||||
useButton = self.__CreateButton(148, 192 + (slot - 1) * 11, 42, "Use")
|
|
||||||
useButton.SetEvent(self.__SendUseSlot, slot)
|
|
||||||
self.slotRows.append((label, saveButton, useButton))
|
|
||||||
|
|
||||||
def __CreateValueLine(self, x, y):
|
|
||||||
textLine = ui.TextLine()
|
|
||||||
textLine.SetParent(self)
|
|
||||||
textLine.SetPosition(x, y)
|
|
||||||
textLine.SetOutline()
|
|
||||||
textLine.Show()
|
|
||||||
return textLine
|
|
||||||
|
|
||||||
def __CreateButton(self, x, y, width, text):
|
|
||||||
button = ui.Button()
|
|
||||||
button.SetParent(self)
|
|
||||||
button.SetPosition(x, y)
|
|
||||||
button.SetUpVisual("d:/ymir work/ui/public/small_thin_button_01.sub")
|
|
||||||
button.SetOverVisual("d:/ymir work/ui/public/small_thin_button_02.sub")
|
|
||||||
button.SetDownVisual("d:/ymir work/ui/public/small_thin_button_03.sub")
|
|
||||||
button.SetDisableVisual("d:/ymir work/ui/public/small_thin_button_01.sub")
|
|
||||||
button.SetSize(width, 17)
|
|
||||||
button.SetText(text)
|
|
||||||
button.Show()
|
|
||||||
return button
|
|
||||||
|
|
||||||
def __GetTeleportQuestData(self):
|
|
||||||
questCount = min(quest.GetQuestCount(), quest.QUEST_MAX_NUM)
|
|
||||||
for questIndex in range(questCount):
|
|
||||||
(questName, questIcon, questCounterName, questCounterValue) = quest.GetQuestData(questIndex)
|
|
||||||
if questName != self.TITLE:
|
|
||||||
continue
|
|
||||||
|
|
||||||
maxSlots = 3
|
|
||||||
if "/" in questCounterName:
|
|
||||||
parts = questCounterName.split("/")
|
|
||||||
try:
|
|
||||||
maxSlots = int(parts[-1].strip())
|
|
||||||
except:
|
|
||||||
maxSlots = 3
|
|
||||||
|
|
||||||
(clockName, clockValue) = quest.GetQuestLastTime(questIndex)
|
|
||||||
return {
|
|
||||||
"savedCount" : max(questCounterValue, 0),
|
|
||||||
"maxSlots" : max(maxSlots, 3),
|
|
||||||
"clockName" : clockName,
|
|
||||||
"clockValue" : max(clockValue, 0),
|
|
||||||
}
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def __FormatCooldown(self, seconds):
|
|
||||||
return "%02d:%02d" % (seconds // 60, seconds % 60)
|
|
||||||
|
|
||||||
def __RefreshSlotRows(self, maxSlots):
|
|
||||||
for slot, row in enumerate(self.slotRows, 1):
|
|
||||||
(label, saveButton, useButton) = row
|
|
||||||
if slot <= maxSlots:
|
|
||||||
label.SetText("Slot %d" % slot)
|
|
||||||
saveButton.Enable()
|
|
||||||
useButton.Enable()
|
|
||||||
else:
|
|
||||||
label.SetText("Slot %d (VIP)" % slot)
|
|
||||||
saveButton.Disable()
|
|
||||||
useButton.Disable()
|
|
||||||
|
|
||||||
def Refresh(self):
|
|
||||||
teleportData = self.__GetTeleportQuestData()
|
|
||||||
(x, y, z) = player.GetMainCharacterPosition()
|
|
||||||
currentMap = background.GetCurrentMapName()
|
|
||||||
|
|
||||||
self.mapLine.SetText("Map: %s" % currentMap)
|
|
||||||
self.coordLine.SetText("Coords: %d, %d" % (x // 100, y // 100))
|
|
||||||
|
|
||||||
if not teleportData:
|
|
||||||
self.statusLine.SetText("Status: Waiting for teleport quest")
|
|
||||||
self.slotSummaryLine.SetText("Saved: -")
|
|
||||||
self.cooldownLine.SetText("Cooldown: -")
|
|
||||||
self.__RefreshSlotRows(3)
|
|
||||||
return
|
|
||||||
|
|
||||||
self.statusLine.SetText("Status: %s" % ("Cooldown" if teleportData["clockValue"] > 0 else "Ready"))
|
|
||||||
self.slotSummaryLine.SetText("Saved: %d / %d" % (teleportData["savedCount"], teleportData["maxSlots"]))
|
|
||||||
if teleportData["clockValue"] > 0 and len(teleportData["clockName"]) > 0:
|
|
||||||
self.cooldownLine.SetText("Cooldown: %s" % self.__FormatCooldown(teleportData["clockValue"]))
|
|
||||||
else:
|
|
||||||
self.cooldownLine.SetText("Cooldown: Ready")
|
|
||||||
|
|
||||||
self.__RefreshSlotRows(teleportData["maxSlots"])
|
|
||||||
|
|
||||||
def Show(self):
|
|
||||||
self.Refresh()
|
|
||||||
ui.BoardWithTitleBar.Show(self)
|
|
||||||
|
|
||||||
def OnUpdate(self):
|
|
||||||
currentTime = time.time()
|
|
||||||
if currentTime - self.lastRefreshTime < 0.2:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.lastRefreshTime = currentTime
|
|
||||||
self.Refresh()
|
|
||||||
|
|
||||||
def __SendTeleportCommand(self, action, arg):
|
|
||||||
net.SendChatPacket("/teleport_system %s %d" % (action, arg), 0)
|
|
||||||
self.lastRefreshTime = 0.0
|
|
||||||
self.Refresh()
|
|
||||||
|
|
||||||
def __SendSaveSlot(self, slot):
|
|
||||||
self.__SendTeleportCommand("save", slot)
|
|
||||||
|
|
||||||
def __SendUseSlot(self, slot):
|
|
||||||
self.__SendTeleportCommand("saved", slot)
|
|
||||||
|
|
||||||
def __SendPresetWarp(self, presetId):
|
|
||||||
self.__SendTeleportCommand("preset", presetId)
|
|
||||||
@@ -8,7 +8,6 @@ import localeInfo
|
|||||||
import constInfo
|
import constInfo
|
||||||
import chrmgr
|
import chrmgr
|
||||||
import player
|
import player
|
||||||
import uiAutopickup
|
|
||||||
import uiPrivateShopBuilder # 占쏙옙占쏙옙호
|
import uiPrivateShopBuilder # 占쏙옙占쏙옙호
|
||||||
import interfaceModule # 占쏙옙占쏙옙호
|
import interfaceModule # 占쏙옙占쏙옙호
|
||||||
|
|
||||||
@@ -40,14 +39,8 @@ class OptionDialog(ui.ScriptWindow):
|
|||||||
self.alwaysShowNameButtonList = []
|
self.alwaysShowNameButtonList = []
|
||||||
self.showDamageButtonList = []
|
self.showDamageButtonList = []
|
||||||
self.showsalesTextButtonList = []
|
self.showsalesTextButtonList = []
|
||||||
self.autoPickupButton = None
|
|
||||||
self.autoPickupDialog = None
|
|
||||||
|
|
||||||
def Destroy(self):
|
def Destroy(self):
|
||||||
if self.autoPickupDialog:
|
|
||||||
self.autoPickupDialog.Destroy()
|
|
||||||
self.autoPickupDialog = None
|
|
||||||
|
|
||||||
self.ClearDictionary()
|
self.ClearDictionary()
|
||||||
|
|
||||||
self.__Initialize()
|
self.__Initialize()
|
||||||
@@ -87,7 +80,6 @@ class OptionDialog(ui.ScriptWindow):
|
|||||||
self.showDamageButtonList.append(GetObject("show_damage_off_button"))
|
self.showDamageButtonList.append(GetObject("show_damage_off_button"))
|
||||||
self.showsalesTextButtonList.append(GetObject("salestext_on_button"))
|
self.showsalesTextButtonList.append(GetObject("salestext_on_button"))
|
||||||
self.showsalesTextButtonList.append(GetObject("salestext_off_button"))
|
self.showsalesTextButtonList.append(GetObject("salestext_off_button"))
|
||||||
self.autoPickupButton = GetObject("autopickup_button")
|
|
||||||
|
|
||||||
except:
|
except:
|
||||||
import exception
|
import exception
|
||||||
@@ -138,7 +130,6 @@ class OptionDialog(ui.ScriptWindow):
|
|||||||
|
|
||||||
self.showsalesTextButtonList[0].SAFE_SetEvent(self.__OnClickSalesTextOnButton)
|
self.showsalesTextButtonList[0].SAFE_SetEvent(self.__OnClickSalesTextOnButton)
|
||||||
self.showsalesTextButtonList[1].SAFE_SetEvent(self.__OnClickSalesTextOffButton)
|
self.showsalesTextButtonList[1].SAFE_SetEvent(self.__OnClickSalesTextOffButton)
|
||||||
self.autoPickupButton.SAFE_SetEvent(self.__OnClickAutoPickupButton)
|
|
||||||
|
|
||||||
self.__ClickRadioButton(self.nameColorModeButtonList, constInfo.GET_CHRNAME_COLOR_INDEX())
|
self.__ClickRadioButton(self.nameColorModeButtonList, constInfo.GET_CHRNAME_COLOR_INDEX())
|
||||||
self.__ClickRadioButton(self.viewTargetBoardButtonList, constInfo.GET_VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD())
|
self.__ClickRadioButton(self.viewTargetBoardButtonList, constInfo.GET_VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD())
|
||||||
@@ -250,15 +241,6 @@ class OptionDialog(ui.ScriptWindow):
|
|||||||
def __OnClickSalesTextOffButton(self):
|
def __OnClickSalesTextOffButton(self):
|
||||||
systemSetting.SetShowSalesTextFlag(False)
|
systemSetting.SetShowSalesTextFlag(False)
|
||||||
self.RefreshShowSalesText()
|
self.RefreshShowSalesText()
|
||||||
|
|
||||||
def __OnClickAutoPickupButton(self):
|
|
||||||
if not self.autoPickupDialog:
|
|
||||||
self.autoPickupDialog = uiAutopickup.AutoPickupWindow()
|
|
||||||
|
|
||||||
if self.autoPickupDialog.IsShow():
|
|
||||||
self.autoPickupDialog.Hide()
|
|
||||||
else:
|
|
||||||
self.autoPickupDialog.Show()
|
|
||||||
|
|
||||||
def __CheckPvPProtectedLevelPlayer(self):
|
def __CheckPvPProtectedLevelPlayer(self):
|
||||||
if player.GetStatus(player.LEVEL)<constInfo.PVPMODE_PROTECTED_LEVEL:
|
if player.GetStatus(player.LEVEL)<constInfo.PVPMODE_PROTECTED_LEVEL:
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import grp
|
|||||||
import uiScriptLocale
|
import uiScriptLocale
|
||||||
import uiRefine
|
import uiRefine
|
||||||
import uiAttachMetin
|
import uiAttachMetin
|
||||||
import uiStoneQueue
|
|
||||||
import uiPickMoney
|
import uiPickMoney
|
||||||
import uiCommon
|
import uiCommon
|
||||||
import uiPrivateShopBuilder # Prevent ItemMove while private shop is open
|
import uiPrivateShopBuilder # Prevent ItemMove while private shop is open
|
||||||
@@ -24,12 +23,6 @@ ITEM_FLAG_APPLICABLE = 1 << 14
|
|||||||
|
|
||||||
class CostumeWindow(ui.ScriptWindow):
|
class CostumeWindow(ui.ScriptWindow):
|
||||||
|
|
||||||
SLOT_ORDER = (
|
|
||||||
item.COSTUME_SLOT_BODY,
|
|
||||||
item.COSTUME_SLOT_HAIR,
|
|
||||||
item.COSTUME_SLOT_SASH,
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self, wndInventory):
|
def __init__(self, wndInventory):
|
||||||
import exception
|
import exception
|
||||||
|
|
||||||
@@ -94,7 +87,8 @@ class CostumeWindow(ui.ScriptWindow):
|
|||||||
def RefreshCostumeSlot(self):
|
def RefreshCostumeSlot(self):
|
||||||
getItemVNum=player.GetItemIndex
|
getItemVNum=player.GetItemIndex
|
||||||
|
|
||||||
for slotNumber in self.SLOT_ORDER:
|
for i in range(item.COSTUME_SLOT_COUNT):
|
||||||
|
slotNumber = item.COSTUME_SLOT_START + i
|
||||||
self.wndEquip.SetItemSlot(slotNumber, getItemVNum(slotNumber), 0)
|
self.wndEquip.SetItemSlot(slotNumber, getItemVNum(slotNumber), 0)
|
||||||
|
|
||||||
self.wndEquip.RefreshSlot()
|
self.wndEquip.RefreshSlot()
|
||||||
@@ -257,13 +251,11 @@ class InventoryWindow(ui.ScriptWindow):
|
|||||||
isLoaded = 0
|
isLoaded = 0
|
||||||
isOpenedCostumeWindowWhenClosingInventory = 0 # Whether costume window was open when closing inventory
|
isOpenedCostumeWindowWhenClosingInventory = 0 # Whether costume window was open when closing inventory
|
||||||
isOpenedBeltWindowWhenClosingInventory = 0 # Whether belt inventory was open when closing inventory
|
isOpenedBeltWindowWhenClosingInventory = 0 # Whether belt inventory was open when closing inventory
|
||||||
sashAbsorbSlot = -1
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
ui.ScriptWindow.__init__(self)
|
ui.ScriptWindow.__init__(self)
|
||||||
|
|
||||||
self.isOpenedBeltWindowWhenClosingInventory = 0 # Whether belt inventory was open when closing inventory
|
self.isOpenedBeltWindowWhenClosingInventory = 0 # Whether belt inventory was open when closing inventory
|
||||||
self.sashAbsorbSlot = -1
|
|
||||||
|
|
||||||
self.__LoadWindow()
|
self.__LoadWindow()
|
||||||
|
|
||||||
@@ -365,10 +357,6 @@ class InventoryWindow(ui.ScriptWindow):
|
|||||||
self.attachMetinDialog = uiAttachMetin.AttachMetinDialog()
|
self.attachMetinDialog = uiAttachMetin.AttachMetinDialog()
|
||||||
self.attachMetinDialog.Hide()
|
self.attachMetinDialog.Hide()
|
||||||
|
|
||||||
## StoneQueueDialog
|
|
||||||
self.stoneQueueDialog = uiStoneQueue.StoneQueueWindow()
|
|
||||||
self.stoneQueueDialog.Hide()
|
|
||||||
|
|
||||||
## MoneySlot
|
## MoneySlot
|
||||||
self.wndMoneySlot.SetEvent(ui.__mem_func__(self.OpenPickMoneyDialog))
|
self.wndMoneySlot.SetEvent(ui.__mem_func__(self.OpenPickMoneyDialog))
|
||||||
|
|
||||||
@@ -419,9 +407,6 @@ class InventoryWindow(ui.ScriptWindow):
|
|||||||
self.attachMetinDialog.Destroy()
|
self.attachMetinDialog.Destroy()
|
||||||
self.attachMetinDialog = 0
|
self.attachMetinDialog = 0
|
||||||
|
|
||||||
self.stoneQueueDialog.Destroy()
|
|
||||||
self.stoneQueueDialog = 0
|
|
||||||
|
|
||||||
self.tooltipItem = None
|
self.tooltipItem = None
|
||||||
self.wndItem = 0
|
self.wndItem = 0
|
||||||
self.wndEquip = 0
|
self.wndEquip = 0
|
||||||
@@ -446,7 +431,6 @@ class InventoryWindow(ui.ScriptWindow):
|
|||||||
self.equipmentTab = []
|
self.equipmentTab = []
|
||||||
|
|
||||||
def Hide(self):
|
def Hide(self):
|
||||||
self.__AbortSashAbsorb(False)
|
|
||||||
if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS():
|
if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS():
|
||||||
self.OnCloseQuestionDialog()
|
self.OnCloseQuestionDialog()
|
||||||
return
|
return
|
||||||
@@ -471,91 +455,6 @@ class InventoryWindow(ui.ScriptWindow):
|
|||||||
def Close(self):
|
def Close(self):
|
||||||
self.Hide()
|
self.Hide()
|
||||||
|
|
||||||
def __AbortSashAbsorb(self, showMessage=True):
|
|
||||||
if self.sashAbsorbSlot == -1:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.sashAbsorbSlot = -1
|
|
||||||
if showMessage:
|
|
||||||
chat.AppendChat(chat.CHAT_TYPE_INFO, "Sash absorb canceled.")
|
|
||||||
|
|
||||||
def __IsSashItem(self, slotIndex):
|
|
||||||
itemVnum = player.GetItemIndex(slotIndex)
|
|
||||||
if not itemVnum:
|
|
||||||
return False
|
|
||||||
|
|
||||||
item.SelectItem(itemVnum)
|
|
||||||
return item.GetItemType() == item.ITEM_TYPE_COSTUME and item.GetItemSubType() == item.COSTUME_TYPE_SASH
|
|
||||||
|
|
||||||
def __CanAbsorbIntoSash(self, sashSlot, targetSlot):
|
|
||||||
if sashSlot == targetSlot:
|
|
||||||
return False
|
|
||||||
|
|
||||||
if player.IsEquipmentSlot(sashSlot) or player.IsEquipmentSlot(targetSlot):
|
|
||||||
return False
|
|
||||||
|
|
||||||
if player.GetItemMetinSocket(sashSlot, 0):
|
|
||||||
return False
|
|
||||||
|
|
||||||
targetVnum = player.GetItemIndex(targetSlot)
|
|
||||||
if not targetVnum:
|
|
||||||
return False
|
|
||||||
|
|
||||||
item.SelectItem(targetVnum)
|
|
||||||
itemType = item.GetItemType()
|
|
||||||
itemSubType = item.GetItemSubType()
|
|
||||||
|
|
||||||
if itemType == item.ITEM_TYPE_WEAPON:
|
|
||||||
return itemSubType != item.WEAPON_ARROW
|
|
||||||
|
|
||||||
if itemType != item.ITEM_TYPE_ARMOR:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return itemSubType in (
|
|
||||||
item.ARMOR_BODY,
|
|
||||||
item.ARMOR_HEAD,
|
|
||||||
item.ARMOR_SHIELD,
|
|
||||||
item.ARMOR_WRIST,
|
|
||||||
item.ARMOR_FOOTS,
|
|
||||||
item.ARMOR_NECK,
|
|
||||||
item.ARMOR_EAR,
|
|
||||||
)
|
|
||||||
|
|
||||||
def __BeginSashAbsorb(self, sashSlot):
|
|
||||||
if player.IsEquipmentSlot(sashSlot):
|
|
||||||
chat.AppendChat(chat.CHAT_TYPE_INFO, "Unequip the sash before absorbing bonuses.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if player.GetItemMetinSocket(sashSlot, 0):
|
|
||||||
chat.AppendChat(chat.CHAT_TYPE_INFO, "This sash already contains absorbed bonuses.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.sashAbsorbSlot == sashSlot:
|
|
||||||
self.__AbortSashAbsorb()
|
|
||||||
return
|
|
||||||
|
|
||||||
self.sashAbsorbSlot = sashSlot
|
|
||||||
chat.AppendChat(chat.CHAT_TYPE_INFO, "Select a weapon or armor piece to absorb into the sash.")
|
|
||||||
|
|
||||||
def __OpenSashAbsorbQuestion(self, sashSlot, targetSlot):
|
|
||||||
targetVnum = player.GetItemIndex(targetSlot)
|
|
||||||
item.SelectItem(targetVnum)
|
|
||||||
targetName = item.GetItemName()
|
|
||||||
|
|
||||||
self.questionDialog = uiCommon.QuestionDialog()
|
|
||||||
self.questionDialog.SetText("Absorb bonuses from %s? The source item will be destroyed." % targetName)
|
|
||||||
self.questionDialog.SetAcceptEvent(ui.__mem_func__(self.__AcceptSashAbsorb))
|
|
||||||
self.questionDialog.SetCancelEvent(ui.__mem_func__(self.OnCloseQuestionDialog))
|
|
||||||
self.questionDialog.sashSlot = sashSlot
|
|
||||||
self.questionDialog.targetSlot = targetSlot
|
|
||||||
self.questionDialog.Open()
|
|
||||||
constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(1)
|
|
||||||
|
|
||||||
def __AcceptSashAbsorb(self):
|
|
||||||
net.SendChatPacket("/sash absorb %d %d" % (self.questionDialog.sashSlot, self.questionDialog.targetSlot), 0)
|
|
||||||
self.__AbortSashAbsorb(False)
|
|
||||||
self.OnCloseQuestionDialog()
|
|
||||||
|
|
||||||
def SetInventoryPage(self, page):
|
def SetInventoryPage(self, page):
|
||||||
self.inventoryPageIndex = page
|
self.inventoryPageIndex = page
|
||||||
self.inventoryTab[1-page].SetUp()
|
self.inventoryTab[1-page].SetUp()
|
||||||
@@ -802,18 +701,6 @@ class InventoryWindow(ui.ScriptWindow):
|
|||||||
|
|
||||||
itemSlotIndex = self.__InventoryLocalSlotPosToGlobalSlotPos(itemSlotIndex)
|
itemSlotIndex = self.__InventoryLocalSlotPosToGlobalSlotPos(itemSlotIndex)
|
||||||
|
|
||||||
if self.sashAbsorbSlot != -1 and not mouseModule.mouseController.isAttached():
|
|
||||||
if itemSlotIndex == self.sashAbsorbSlot:
|
|
||||||
self.__AbortSashAbsorb()
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.__CanAbsorbIntoSash(self.sashAbsorbSlot, itemSlotIndex):
|
|
||||||
self.__OpenSashAbsorbQuestion(self.sashAbsorbSlot, itemSlotIndex)
|
|
||||||
else:
|
|
||||||
chat.AppendChat(chat.CHAT_TYPE_INFO, "Only unequipped weapon or armor items can be absorbed.")
|
|
||||||
self.__AbortSashAbsorb(False)
|
|
||||||
return
|
|
||||||
|
|
||||||
if mouseModule.mouseController.isAttached():
|
if mouseModule.mouseController.isAttached():
|
||||||
attachedSlotType = mouseModule.mouseController.GetAttachedType()
|
attachedSlotType = mouseModule.mouseController.GetAttachedType()
|
||||||
attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber()
|
attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber()
|
||||||
@@ -954,6 +841,20 @@ class InventoryWindow(ui.ScriptWindow):
|
|||||||
scrollIndex = player.GetItemIndex(scrollSlotPos)
|
scrollIndex = player.GetItemIndex(scrollSlotPos)
|
||||||
targetIndex = player.GetItemIndex(targetSlotPos)
|
targetIndex = player.GetItemIndex(targetSlotPos)
|
||||||
|
|
||||||
|
if player.REFINE_OK != player.CanRefine(scrollIndex, targetSlotPos):
|
||||||
|
return
|
||||||
|
|
||||||
|
###########################################################
|
||||||
|
self.__SendUseItemToItemPacket(scrollSlotPos, targetSlotPos)
|
||||||
|
#net.SendItemUseToItemPacket(scrollSlotPos, targetSlotPos)
|
||||||
|
return
|
||||||
|
###########################################################
|
||||||
|
|
||||||
|
###########################################################
|
||||||
|
#net.SendRequestRefineInfoPacket(targetSlotPos)
|
||||||
|
#return
|
||||||
|
###########################################################
|
||||||
|
|
||||||
result = player.CanRefine(scrollIndex, targetSlotPos)
|
result = player.CanRefine(scrollIndex, targetSlotPos)
|
||||||
|
|
||||||
if player.REFINE_ALREADY_MAX_SOCKET_COUNT == result:
|
if player.REFINE_ALREADY_MAX_SOCKET_COUNT == result:
|
||||||
@@ -978,12 +879,7 @@ class InventoryWindow(ui.ScriptWindow):
|
|||||||
if player.REFINE_OK != result:
|
if player.REFINE_OK != result:
|
||||||
return
|
return
|
||||||
|
|
||||||
item.SelectItem(targetIndex)
|
self.refineDialog.Open(scrollSlotPos, targetSlotPos)
|
||||||
if item.GetItemType() == item.ITEM_TYPE_METIN:
|
|
||||||
self.stoneQueueDialog.Open(scrollSlotPos, targetSlotPos)
|
|
||||||
return
|
|
||||||
|
|
||||||
self.__SendUseItemToItemPacket(scrollSlotPos, targetSlotPos)
|
|
||||||
|
|
||||||
def DetachMetinFromItem(self, scrollSlotPos, targetSlotPos):
|
def DetachMetinFromItem(self, scrollSlotPos, targetSlotPos):
|
||||||
scrollIndex = player.GetItemIndex(scrollSlotPos)
|
scrollIndex = player.GetItemIndex(scrollSlotPos)
|
||||||
@@ -1310,11 +1206,6 @@ class InventoryWindow(ui.ScriptWindow):
|
|||||||
def __UseItem(self, slotIndex):
|
def __UseItem(self, slotIndex):
|
||||||
ItemVNum = player.GetItemIndex(slotIndex)
|
ItemVNum = player.GetItemIndex(slotIndex)
|
||||||
item.SelectItem(ItemVNum)
|
item.SelectItem(ItemVNum)
|
||||||
|
|
||||||
if self.__IsSashItem(slotIndex):
|
|
||||||
self.__BeginSashAbsorb(slotIndex)
|
|
||||||
return
|
|
||||||
|
|
||||||
if item.IsFlag(item.ITEM_FLAG_CONFIRM_WHEN_USE):
|
if item.IsFlag(item.ITEM_FLAG_CONFIRM_WHEN_USE):
|
||||||
self.questionDialog = uiCommon.QuestionDialog()
|
self.questionDialog = uiCommon.QuestionDialog()
|
||||||
self.questionDialog.SetText(localeInfo.INVENTORY_REALLY_USE_ITEM)
|
self.questionDialog.SetText(localeInfo.INVENTORY_REALLY_USE_ITEM)
|
||||||
|
|||||||
@@ -222,15 +222,6 @@ class MiniMap(ui.ScriptWindow):
|
|||||||
self.tooltipAtlasOpen = MapTextToolTip()
|
self.tooltipAtlasOpen = MapTextToolTip()
|
||||||
self.tooltipAtlasOpen.SetText(localeInfo.MINIMAP_SHOW_AREAMAP)
|
self.tooltipAtlasOpen.SetText(localeInfo.MINIMAP_SHOW_AREAMAP)
|
||||||
self.tooltipAtlasOpen.Show()
|
self.tooltipAtlasOpen.Show()
|
||||||
self.tooltipBiolog = MapTextToolTip()
|
|
||||||
self.tooltipBiolog.SetText("Biolog")
|
|
||||||
self.tooltipBiolog.Show()
|
|
||||||
self.tooltipTeleport = MapTextToolTip()
|
|
||||||
self.tooltipTeleport.SetText("Teleport")
|
|
||||||
self.tooltipTeleport.Show()
|
|
||||||
self.tooltipSwitchbot = MapTextToolTip()
|
|
||||||
self.tooltipSwitchbot.SetText("Switchbot")
|
|
||||||
self.tooltipSwitchbot.Show()
|
|
||||||
self.tooltipInfo = MapTextToolTip()
|
self.tooltipInfo = MapTextToolTip()
|
||||||
self.tooltipInfo.Show()
|
self.tooltipInfo.Show()
|
||||||
|
|
||||||
@@ -268,21 +259,12 @@ class MiniMap(ui.ScriptWindow):
|
|||||||
self.MiniMapHideButton = 0
|
self.MiniMapHideButton = 0
|
||||||
self.MiniMapShowButton = 0
|
self.MiniMapShowButton = 0
|
||||||
self.AtlasShowButton = 0
|
self.AtlasShowButton = 0
|
||||||
self.BiologButton = 0
|
|
||||||
self.TeleportButton = 0
|
|
||||||
self.SwitchbotButton = 0
|
|
||||||
self.biologButtonEvent = None
|
|
||||||
self.teleportButtonEvent = None
|
|
||||||
self.switchbotButtonEvent = None
|
|
||||||
|
|
||||||
self.tooltipMiniMapOpen = 0
|
self.tooltipMiniMapOpen = 0
|
||||||
self.tooltipMiniMapClose = 0
|
self.tooltipMiniMapClose = 0
|
||||||
self.tooltipScaleUp = 0
|
self.tooltipScaleUp = 0
|
||||||
self.tooltipScaleDown = 0
|
self.tooltipScaleDown = 0
|
||||||
self.tooltipAtlasOpen = 0
|
self.tooltipAtlasOpen = 0
|
||||||
self.tooltipBiolog = 0
|
|
||||||
self.tooltipTeleport = 0
|
|
||||||
self.tooltipSwitchbot = 0
|
|
||||||
self.tooltipInfo = None
|
self.tooltipInfo = None
|
||||||
self.serverInfo = None
|
self.serverInfo = None
|
||||||
|
|
||||||
@@ -364,39 +346,6 @@ class MiniMap(ui.ScriptWindow):
|
|||||||
if miniMap.IsAtlas():
|
if miniMap.IsAtlas():
|
||||||
self.AtlasShowButton.SetEvent(ui.__mem_func__(self.ShowAtlas))
|
self.AtlasShowButton.SetEvent(ui.__mem_func__(self.ShowAtlas))
|
||||||
|
|
||||||
self.BiologButton = ui.Button()
|
|
||||||
self.BiologButton.SetParent(self.OpenWindow)
|
|
||||||
self.BiologButton.SetPosition(9, 111)
|
|
||||||
self.BiologButton.SetUpVisual("d:/ymir work/ui/public/small_thin_button_01.sub")
|
|
||||||
self.BiologButton.SetOverVisual("d:/ymir work/ui/public/small_thin_button_02.sub")
|
|
||||||
self.BiologButton.SetDownVisual("d:/ymir work/ui/public/small_thin_button_03.sub")
|
|
||||||
self.BiologButton.SetText("Bio")
|
|
||||||
if self.biologButtonEvent:
|
|
||||||
self.BiologButton.SetEvent(self.biologButtonEvent)
|
|
||||||
self.BiologButton.Show()
|
|
||||||
|
|
||||||
self.TeleportButton = ui.Button()
|
|
||||||
self.TeleportButton.SetParent(self.OpenWindow)
|
|
||||||
self.TeleportButton.SetPosition(9, 132)
|
|
||||||
self.TeleportButton.SetUpVisual("d:/ymir work/ui/public/small_thin_button_01.sub")
|
|
||||||
self.TeleportButton.SetOverVisual("d:/ymir work/ui/public/small_thin_button_02.sub")
|
|
||||||
self.TeleportButton.SetDownVisual("d:/ymir work/ui/public/small_thin_button_03.sub")
|
|
||||||
self.TeleportButton.SetText("TP")
|
|
||||||
if self.teleportButtonEvent:
|
|
||||||
self.TeleportButton.SetEvent(self.teleportButtonEvent)
|
|
||||||
self.TeleportButton.Show()
|
|
||||||
|
|
||||||
self.SwitchbotButton = ui.Button()
|
|
||||||
self.SwitchbotButton.SetParent(self.OpenWindow)
|
|
||||||
self.SwitchbotButton.SetPosition(9, 153)
|
|
||||||
self.SwitchbotButton.SetUpVisual("d:/ymir work/ui/public/small_thin_button_01.sub")
|
|
||||||
self.SwitchbotButton.SetOverVisual("d:/ymir work/ui/public/small_thin_button_02.sub")
|
|
||||||
self.SwitchbotButton.SetDownVisual("d:/ymir work/ui/public/small_thin_button_03.sub")
|
|
||||||
self.SwitchbotButton.SetText("Sw")
|
|
||||||
if self.switchbotButtonEvent:
|
|
||||||
self.SwitchbotButton.SetEvent(self.switchbotButtonEvent)
|
|
||||||
self.SwitchbotButton.Show()
|
|
||||||
|
|
||||||
(ButtonPosX, ButtonPosY) = self.MiniMapShowButton.GetGlobalPosition()
|
(ButtonPosX, ButtonPosY) = self.MiniMapShowButton.GetGlobalPosition()
|
||||||
self.tooltipMiniMapOpen.SetTooltipPosition(ButtonPosX, ButtonPosY)
|
self.tooltipMiniMapOpen.SetTooltipPosition(ButtonPosX, ButtonPosY)
|
||||||
|
|
||||||
@@ -412,15 +361,6 @@ class MiniMap(ui.ScriptWindow):
|
|||||||
(ButtonPosX, ButtonPosY) = self.AtlasShowButton.GetGlobalPosition()
|
(ButtonPosX, ButtonPosY) = self.AtlasShowButton.GetGlobalPosition()
|
||||||
self.tooltipAtlasOpen.SetTooltipPosition(ButtonPosX, ButtonPosY)
|
self.tooltipAtlasOpen.SetTooltipPosition(ButtonPosX, ButtonPosY)
|
||||||
|
|
||||||
(ButtonPosX, ButtonPosY) = self.BiologButton.GetGlobalPosition()
|
|
||||||
self.tooltipBiolog.SetTooltipPosition(ButtonPosX, ButtonPosY)
|
|
||||||
|
|
||||||
(ButtonPosX, ButtonPosY) = self.TeleportButton.GetGlobalPosition()
|
|
||||||
self.tooltipTeleport.SetTooltipPosition(ButtonPosX, ButtonPosY)
|
|
||||||
|
|
||||||
(ButtonPosX, ButtonPosY) = self.SwitchbotButton.GetGlobalPosition()
|
|
||||||
self.tooltipSwitchbot.SetTooltipPosition(ButtonPosX, ButtonPosY)
|
|
||||||
|
|
||||||
self.ShowMiniMap()
|
self.ShowMiniMap()
|
||||||
|
|
||||||
def Destroy(self):
|
def Destroy(self):
|
||||||
@@ -501,21 +441,6 @@ class MiniMap(ui.ScriptWindow):
|
|||||||
else:
|
else:
|
||||||
self.tooltipAtlasOpen.Hide()
|
self.tooltipAtlasOpen.Hide()
|
||||||
|
|
||||||
if True == self.BiologButton.IsIn():
|
|
||||||
self.tooltipBiolog.Show()
|
|
||||||
else:
|
|
||||||
self.tooltipBiolog.Hide()
|
|
||||||
|
|
||||||
if True == self.TeleportButton.IsIn():
|
|
||||||
self.tooltipTeleport.Show()
|
|
||||||
else:
|
|
||||||
self.tooltipTeleport.Hide()
|
|
||||||
|
|
||||||
if True == self.SwitchbotButton.IsIn():
|
|
||||||
self.tooltipSwitchbot.Show()
|
|
||||||
else:
|
|
||||||
self.tooltipSwitchbot.Hide()
|
|
||||||
|
|
||||||
def OnRender(self):
|
def OnRender(self):
|
||||||
(x, y) = self.GetGlobalPosition()
|
(x, y) = self.GetGlobalPosition()
|
||||||
fx = float(x)
|
fx = float(x)
|
||||||
@@ -560,18 +485,3 @@ class MiniMap(ui.ScriptWindow):
|
|||||||
self.AtlasWindow.Hide()
|
self.AtlasWindow.Hide()
|
||||||
else:
|
else:
|
||||||
self.AtlasWindow.Show()
|
self.AtlasWindow.Show()
|
||||||
|
|
||||||
def SetBiologButtonEvent(self, event):
|
|
||||||
self.biologButtonEvent = event
|
|
||||||
if self.BiologButton:
|
|
||||||
self.BiologButton.SetEvent(event)
|
|
||||||
|
|
||||||
def SetTeleportButtonEvent(self, event):
|
|
||||||
self.teleportButtonEvent = event
|
|
||||||
if self.TeleportButton:
|
|
||||||
self.TeleportButton.SetEvent(event)
|
|
||||||
|
|
||||||
def SetSwitchbotButtonEvent(self, event):
|
|
||||||
self.switchbotButtonEvent = event
|
|
||||||
if self.SwitchbotButton:
|
|
||||||
self.SwitchbotButton.SetEvent(event)
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class PlayerGauge(ui.Gauge):
|
|||||||
self.SetPosition(-100, -100)
|
self.SetPosition(-100, -100)
|
||||||
ui.Gauge.Hide(self)
|
ui.Gauge.Hide(self)
|
||||||
|
|
||||||
def __UpdateScreenPosition(self):
|
def OnUpdate(self):
|
||||||
playerIndex = player.GetMainCharacterIndex()
|
playerIndex = player.GetMainCharacterIndex()
|
||||||
|
|
||||||
(x, y, z)=textTail.GetPosition(playerIndex)
|
(x, y, z)=textTail.GetPosition(playerIndex)
|
||||||
@@ -30,14 +30,6 @@ class PlayerGauge(ui.Gauge):
|
|||||||
isChat = textTail.IsChat(playerIndex)
|
isChat = textTail.IsChat(playerIndex)
|
||||||
ui.Gauge.SetPosition(self, int(x - self.GetWidth() // 2), int(y + 5) + isChat * 17)
|
ui.Gauge.SetPosition(self, int(x - self.GetWidth() // 2), int(y + 5) + isChat * 17)
|
||||||
|
|
||||||
def OnUpdate(self):
|
|
||||||
self.__UpdateScreenPosition()
|
|
||||||
|
|
||||||
def OnRender(self):
|
|
||||||
# Refresh the anchor every render so the gauge tracks interpolated
|
|
||||||
# character/text-tail positions on high refresh displays.
|
|
||||||
self.__UpdateScreenPosition()
|
|
||||||
|
|
||||||
def RefreshGauge(self):
|
def RefreshGauge(self):
|
||||||
|
|
||||||
self.curHP = player.GetStatus(player.HP)
|
self.curHP = player.GetStatus(player.HP)
|
||||||
|
|||||||
@@ -94,32 +94,24 @@ class PrivateShopAdvertisementBoard(ui.ThinBoard):
|
|||||||
net.SendOnClickPacket(self.vid)
|
net.SendOnClickPacket(self.vid)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __UpdateProjectedPosition(self):
|
def OnUpdate(self):
|
||||||
if not self.vid:
|
if not self.vid:
|
||||||
return
|
return
|
||||||
|
|
||||||
projectVID = None
|
|
||||||
if systemSetting.IsShowSalesText():
|
if systemSetting.IsShowSalesText():
|
||||||
projectVID = self.vid
|
self.Show()
|
||||||
elif player.GetMainCharacterIndex() == self.vid:
|
x, y = chr.GetProjectPosition(self.vid, 220)
|
||||||
projectVID = player.GetMainCharacterIndex()
|
self.SetPosition(x - self.GetWidth()/2, y - self.GetHeight()/2)
|
||||||
|
|
||||||
if projectVID is None:
|
|
||||||
self.Hide()
|
|
||||||
return
|
|
||||||
|
|
||||||
self.Show()
|
|
||||||
x, y = chr.GetProjectPosition(projectVID, 220)
|
|
||||||
self.SetPosition(x - self.GetWidth()/2, y - self.GetHeight()/2)
|
|
||||||
|
|
||||||
def OnUpdate(self):
|
else:
|
||||||
self.__UpdateProjectedPosition()
|
for key in list(g_privateShopAdvertisementBoardDict.keys()):
|
||||||
|
if player.GetMainCharacterIndex() == key: # When the private shop is visible and closed, the player's own shop ID changes.
|
||||||
def OnRender(self):
|
g_privateShopAdvertisementBoardDict[key].Show()
|
||||||
# Keep the board anchored to the interpolated render position instead
|
x, y = chr.GetProjectPosition(player.GetMainCharacterIndex(), 220)
|
||||||
# of the legacy fixed update cadence.
|
g_privateShopAdvertisementBoardDict[key].SetPosition(x - self.GetWidth()/2, y - self.GetHeight()/2)
|
||||||
self.__UpdateProjectedPosition()
|
else:
|
||||||
|
g_privateShopAdvertisementBoardDict[key].Hide()
|
||||||
|
|
||||||
class PrivateShopBuilder(ui.ScriptWindow):
|
class PrivateShopBuilder(ui.ScriptWindow):
|
||||||
|
|
||||||
|
|||||||
@@ -41,9 +41,6 @@ class OptionDialog(ui.ScriptWindow):
|
|||||||
self.cameraModeButtonList = []
|
self.cameraModeButtonList = []
|
||||||
self.fogModeButtonList = []
|
self.fogModeButtonList = []
|
||||||
self.tilingModeButtonList = []
|
self.tilingModeButtonList = []
|
||||||
self.renderFPSButtonList = []
|
|
||||||
self.renderFPSValues = [60, 120, 144, 240, 0]
|
|
||||||
self.performanceHUDButtonList = []
|
|
||||||
self.ctrlShadowQuality = 0
|
self.ctrlShadowQuality = 0
|
||||||
|
|
||||||
def Destroy(self):
|
def Destroy(self):
|
||||||
@@ -75,13 +72,6 @@ class OptionDialog(ui.ScriptWindow):
|
|||||||
self.fogModeButtonList.append(GetObject("fog_level2"))
|
self.fogModeButtonList.append(GetObject("fog_level2"))
|
||||||
self.tilingModeButtonList.append(GetObject("tiling_cpu"))
|
self.tilingModeButtonList.append(GetObject("tiling_cpu"))
|
||||||
self.tilingModeButtonList.append(GetObject("tiling_gpu"))
|
self.tilingModeButtonList.append(GetObject("tiling_gpu"))
|
||||||
self.renderFPSButtonList.append(GetObject("render_fps_60"))
|
|
||||||
self.renderFPSButtonList.append(GetObject("render_fps_120"))
|
|
||||||
self.renderFPSButtonList.append(GetObject("render_fps_144"))
|
|
||||||
self.renderFPSButtonList.append(GetObject("render_fps_240"))
|
|
||||||
self.renderFPSButtonList.append(GetObject("render_fps_max"))
|
|
||||||
self.performanceHUDButtonList.append(GetObject("performance_hud_off"))
|
|
||||||
self.performanceHUDButtonList.append(GetObject("performance_hud_on"))
|
|
||||||
self.tilingApplyButton=GetObject("tiling_apply")
|
self.tilingApplyButton=GetObject("tiling_apply")
|
||||||
#self.ctrlShadowQuality = GetObject("shadow_bar")
|
#self.ctrlShadowQuality = GetObject("shadow_bar")
|
||||||
except:
|
except:
|
||||||
@@ -116,13 +106,6 @@ class OptionDialog(ui.ScriptWindow):
|
|||||||
|
|
||||||
self.tilingModeButtonList[0].SAFE_SetEvent(self.__OnClickTilingModeCPUButton)
|
self.tilingModeButtonList[0].SAFE_SetEvent(self.__OnClickTilingModeCPUButton)
|
||||||
self.tilingModeButtonList[1].SAFE_SetEvent(self.__OnClickTilingModeGPUButton)
|
self.tilingModeButtonList[1].SAFE_SetEvent(self.__OnClickTilingModeGPUButton)
|
||||||
self.renderFPSButtonList[0].SAFE_SetEvent(self.__OnClickRenderFPS60Button)
|
|
||||||
self.renderFPSButtonList[1].SAFE_SetEvent(self.__OnClickRenderFPS120Button)
|
|
||||||
self.renderFPSButtonList[2].SAFE_SetEvent(self.__OnClickRenderFPS144Button)
|
|
||||||
self.renderFPSButtonList[3].SAFE_SetEvent(self.__OnClickRenderFPS240Button)
|
|
||||||
self.renderFPSButtonList[4].SAFE_SetEvent(self.__OnClickRenderFPSMaxButton)
|
|
||||||
self.performanceHUDButtonList[0].SAFE_SetEvent(self.__OnClickPerformanceHUDOffButton)
|
|
||||||
self.performanceHUDButtonList[1].SAFE_SetEvent(self.__OnClickPerformanceHUDOnButton)
|
|
||||||
|
|
||||||
self.tilingApplyButton.SAFE_SetEvent(self.__OnClickTilingApplyButton)
|
self.tilingApplyButton.SAFE_SetEvent(self.__OnClickTilingApplyButton)
|
||||||
|
|
||||||
@@ -132,7 +115,6 @@ class OptionDialog(ui.ScriptWindow):
|
|||||||
self.__ClickRadioButton(self.fogModeButtonList, systemSetting.GetFogLevel())
|
self.__ClickRadioButton(self.fogModeButtonList, systemSetting.GetFogLevel())
|
||||||
# MR-14: -- END OF -- Fog update by Alaric
|
# MR-14: -- END OF -- Fog update by Alaric
|
||||||
self.__ClickRadioButton(self.cameraModeButtonList, constInfo.GET_CAMERA_MAX_DISTANCE_INDEX())
|
self.__ClickRadioButton(self.cameraModeButtonList, constInfo.GET_CAMERA_MAX_DISTANCE_INDEX())
|
||||||
self.RefreshRenderSettings()
|
|
||||||
|
|
||||||
if musicInfo.fieldMusic==musicInfo.METIN2THEMA:
|
if musicInfo.fieldMusic==musicInfo.METIN2THEMA:
|
||||||
self.selectMusicFile.SetText(uiSelectMusic.DEFAULT_THEMA)
|
self.selectMusicFile.SetText(uiSelectMusic.DEFAULT_THEMA)
|
||||||
@@ -197,41 +179,6 @@ class OptionDialog(ui.ScriptWindow):
|
|||||||
|
|
||||||
self.__ClickRadioButton(self.fogModeButtonList, index)
|
self.__ClickRadioButton(self.fogModeButtonList, index)
|
||||||
|
|
||||||
def __ApplyAndSaveConfig(self):
|
|
||||||
systemSetting.ApplyConfig()
|
|
||||||
systemSetting.SaveConfig()
|
|
||||||
|
|
||||||
def __GetRenderFPSButtonIndex(self):
|
|
||||||
renderFPS = systemSetting.GetRenderFPS()
|
|
||||||
if renderFPS <= 0:
|
|
||||||
return len(self.renderFPSValues) - 1
|
|
||||||
|
|
||||||
try:
|
|
||||||
return self.renderFPSValues.index(renderFPS)
|
|
||||||
except ValueError:
|
|
||||||
bestIndex = 0
|
|
||||||
bestDistance = abs(self.renderFPSValues[0] - renderFPS)
|
|
||||||
for index in xrange(len(self.renderFPSValues) - 1):
|
|
||||||
distance = abs(self.renderFPSValues[index] - renderFPS)
|
|
||||||
if distance < bestDistance:
|
|
||||||
bestIndex = index
|
|
||||||
bestDistance = distance
|
|
||||||
return bestIndex
|
|
||||||
|
|
||||||
def RefreshRenderSettings(self):
|
|
||||||
self.__ClickRadioButton(self.renderFPSButtonList, self.__GetRenderFPSButtonIndex())
|
|
||||||
self.__ClickRadioButton(self.performanceHUDButtonList, 1 if systemSetting.IsShowPerformanceHUD() else 0)
|
|
||||||
|
|
||||||
def __SetRenderFPS(self, fps):
|
|
||||||
systemSetting.SetRenderFPS(fps)
|
|
||||||
self.__ApplyAndSaveConfig()
|
|
||||||
self.RefreshRenderSettings()
|
|
||||||
|
|
||||||
def __SetPerformanceHUD(self, isVisible):
|
|
||||||
systemSetting.SetShowPerformanceHUDFlag(1 if isVisible else 0)
|
|
||||||
self.__ApplyAndSaveConfig()
|
|
||||||
self.RefreshRenderSettings()
|
|
||||||
|
|
||||||
def __OnClickCameraModeShortButton(self):
|
def __OnClickCameraModeShortButton(self):
|
||||||
self.__SetCameraMode(0)
|
self.__SetCameraMode(0)
|
||||||
|
|
||||||
@@ -247,27 +194,6 @@ class OptionDialog(ui.ScriptWindow):
|
|||||||
def __OnClickFogModeLevel2Button(self):
|
def __OnClickFogModeLevel2Button(self):
|
||||||
self.__SetFogLevel(2)
|
self.__SetFogLevel(2)
|
||||||
|
|
||||||
def __OnClickRenderFPS60Button(self):
|
|
||||||
self.__SetRenderFPS(60)
|
|
||||||
|
|
||||||
def __OnClickRenderFPS120Button(self):
|
|
||||||
self.__SetRenderFPS(120)
|
|
||||||
|
|
||||||
def __OnClickRenderFPS144Button(self):
|
|
||||||
self.__SetRenderFPS(144)
|
|
||||||
|
|
||||||
def __OnClickRenderFPS240Button(self):
|
|
||||||
self.__SetRenderFPS(240)
|
|
||||||
|
|
||||||
def __OnClickRenderFPSMaxButton(self):
|
|
||||||
self.__SetRenderFPS(0)
|
|
||||||
|
|
||||||
def __OnClickPerformanceHUDOffButton(self):
|
|
||||||
self.__SetPerformanceHUD(False)
|
|
||||||
|
|
||||||
def __OnClickPerformanceHUDOnButton(self):
|
|
||||||
self.__SetPerformanceHUD(True)
|
|
||||||
|
|
||||||
def __OnChangeMusic(self, fileName):
|
def __OnChangeMusic(self, fileName):
|
||||||
self.selectMusicFile.SetText(fileName[:MUSIC_FILENAME_MAX_LEN])
|
self.selectMusicFile.SetText(fileName[:MUSIC_FILENAME_MAX_LEN])
|
||||||
|
|
||||||
@@ -313,8 +239,6 @@ class OptionDialog(ui.ScriptWindow):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def Show(self):
|
def Show(self):
|
||||||
self.RefreshRenderSettings()
|
|
||||||
self.__SetCurTilingMode()
|
|
||||||
ui.ScriptWindow.Show(self)
|
ui.ScriptWindow.Show(self)
|
||||||
|
|
||||||
def Close(self):
|
def Close(self):
|
||||||
|
|||||||
@@ -1021,14 +1021,12 @@ class ItemToolTip(ToolTip):
|
|||||||
isCostumeItem = 0
|
isCostumeItem = 0
|
||||||
isCostumeHair = 0
|
isCostumeHair = 0
|
||||||
isCostumeBody = 0
|
isCostumeBody = 0
|
||||||
isCostumeSash = 0
|
|
||||||
|
|
||||||
if app.ENABLE_COSTUME_SYSTEM:
|
if app.ENABLE_COSTUME_SYSTEM:
|
||||||
if item.ITEM_TYPE_COSTUME == itemType:
|
if item.ITEM_TYPE_COSTUME == itemType:
|
||||||
isCostumeItem = 1
|
isCostumeItem = 1
|
||||||
isCostumeHair = item.COSTUME_TYPE_HAIR == itemSubType
|
isCostumeHair = item.COSTUME_TYPE_HAIR == itemSubType
|
||||||
isCostumeBody = item.COSTUME_TYPE_BODY == itemSubType
|
isCostumeBody = item.COSTUME_TYPE_BODY == itemSubType
|
||||||
isCostumeSash = item.COSTUME_TYPE_SASH == itemSubType
|
|
||||||
|
|
||||||
#dbg.TraceError("IS_COSTUME_ITEM! body(%d) hair(%d)" % (isCostumeBody, isCostumeHair))
|
#dbg.TraceError("IS_COSTUME_ITEM! body(%d) hair(%d)" % (isCostumeBody, isCostumeHair))
|
||||||
|
|
||||||
@@ -1126,15 +1124,6 @@ class ItemToolTip(ToolTip):
|
|||||||
self.__AppendAttributeInformation(attrSlot)
|
self.__AppendAttributeInformation(attrSlot)
|
||||||
|
|
||||||
self.AppendWearableInformation()
|
self.AppendWearableInformation()
|
||||||
|
|
||||||
if isCostumeSash:
|
|
||||||
self.AppendSpace(5)
|
|
||||||
absorbPct = metinSlot[1] if metinSlot and metinSlot[1] else item.GetValue(0)
|
|
||||||
self.AppendTextLine("Absorb rate: %d%%" % absorbPct, self.NORMAL_COLOR)
|
|
||||||
if metinSlot and metinSlot[0]:
|
|
||||||
self.AppendTextLine("Absorbed item vnum: %d" % metinSlot[0], self.NORMAL_COLOR)
|
|
||||||
else:
|
|
||||||
self.AppendTextLine("Right-click the sash, then select an item to absorb.", self.CONDITION_COLOR)
|
|
||||||
|
|
||||||
bHasRealtimeFlag = 0
|
bHasRealtimeFlag = 0
|
||||||
for i in range(item.LIMIT_MAX_NUM):
|
for i in range(item.LIMIT_MAX_NUM):
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
ScriptType CharacterSoundInformation
|
ScriptType CharacterSoundInformation
|
||||||
|
|
||||||
SoundDataCount 2
|
SoundDataCount 2
|
||||||
SoundData00 0.231000 "sound/pc2/assassin/dualhand_sword/combo4.wav"
|
SoundData00 0.066000 "sound/pc2/assassin/dualhand_sword/combo7.wav"
|
||||||
SoundData01 0.198000 "sound/common/swing/a_dh_c_4.wav"
|
SoundData01 0.033000 "sound/common/swing/w_1h_c_2.wav"
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import uiScriptLocale
|
import uiScriptLocale
|
||||||
import item
|
import item
|
||||||
|
|
||||||
|
COSTUME_START_INDEX = item.COSTUME_SLOT_START
|
||||||
|
|
||||||
window = {
|
window = {
|
||||||
"name" : "CostumeWindow",
|
"name" : "CostumeWindow",
|
||||||
|
|
||||||
@@ -69,9 +71,9 @@ window = {
|
|||||||
"height" : 145,
|
"height" : 145,
|
||||||
|
|
||||||
"slot" : (
|
"slot" : (
|
||||||
{"index":item.COSTUME_SLOT_BODY, "x":61, "y":45, "width":32, "height":64},
|
{"index":COSTUME_START_INDEX+0, "x":61, "y":45, "width":32, "height":64},
|
||||||
{"index":item.COSTUME_SLOT_HAIR, "x":61, "y": 8, "width":32, "height":32},
|
{"index":COSTUME_START_INDEX+1, "x":61, "y": 8, "width":32, "height":32},
|
||||||
{"index":item.COSTUME_SLOT_SASH, "x":5, "y":145, "width":32, "height":32},
|
{"index":COSTUME_START_INDEX+2, "x":5, "y":145, "width":32, "height":32},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ window = {
|
|||||||
##{"index":22, "x":75, "y":106, "width":32, "height":32},
|
##{"index":22, "x":75, "y":106, "width":32, "height":32},
|
||||||
## 새 벨트
|
## 새 벨트
|
||||||
{"index":23, "x":39, "y":106, "width":32, "height":32},
|
{"index":23, "x":39, "y":106, "width":32, "height":32},
|
||||||
{"index":24, "x":2, "y":106, "width":32, "height":32},
|
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ window = {
|
|||||||
"y" : 0,
|
"y" : 0,
|
||||||
|
|
||||||
"width" : 300,
|
"width" : 300,
|
||||||
"height" : 25*12+8,
|
"height" : 25*11+8,
|
||||||
|
|
||||||
"children" :
|
"children" :
|
||||||
(
|
(
|
||||||
@@ -32,7 +32,7 @@ window = {
|
|||||||
"y" : 0,
|
"y" : 0,
|
||||||
|
|
||||||
"width" : 300,
|
"width" : 300,
|
||||||
"height" : 25*12+8,
|
"height" : 25*11+8,
|
||||||
|
|
||||||
"children" :
|
"children" :
|
||||||
(
|
(
|
||||||
@@ -433,29 +433,7 @@ window = {
|
|||||||
"default_image" : ROOT_PATH + "middle_button_01.sub",
|
"default_image" : ROOT_PATH + "middle_button_01.sub",
|
||||||
"over_image" : ROOT_PATH + "middle_button_02.sub",
|
"over_image" : ROOT_PATH + "middle_button_02.sub",
|
||||||
"down_image" : ROOT_PATH + "middle_button_03.sub",
|
"down_image" : ROOT_PATH + "middle_button_03.sub",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name" : "autopickup_label",
|
|
||||||
"type" : "text",
|
|
||||||
|
|
||||||
"x" : LINE_LABEL_X,
|
|
||||||
"y" : 265+2,
|
|
||||||
|
|
||||||
"text" : "Auto Pickup",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name" : "autopickup_button",
|
|
||||||
"type" : "button",
|
|
||||||
|
|
||||||
"x" : LINE_DATA_X,
|
|
||||||
"y" : 265,
|
|
||||||
|
|
||||||
"text" : "Configure",
|
|
||||||
|
|
||||||
"default_image" : ROOT_PATH + "middle_button_01.sub",
|
|
||||||
"over_image" : ROOT_PATH + "middle_button_02.sub",
|
|
||||||
"down_image" : ROOT_PATH + "middle_button_03.sub",
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
import uiScriptLocale
|
import uiScriptLocale
|
||||||
|
|
||||||
ROOT_PATH = "d:/ymir work/ui/public/"
|
ROOT_PATH = "d:/ymir work/ui/public/"
|
||||||
OPTION_RENDER_FPS = getattr(uiScriptLocale, "OPTION_RENDER_FPS", "Render FPS")
|
|
||||||
OPTION_RENDER_FPS_MAX = getattr(uiScriptLocale, "OPTION_RENDER_FPS_MAX", "MAX")
|
|
||||||
OPTION_PERFORMANCE_HUD = getattr(uiScriptLocale, "OPTION_PERFORMANCE_HUD", "Perf HUD")
|
|
||||||
OPTION_ON = getattr(uiScriptLocale, "OPTION_ON", "On")
|
|
||||||
OPTION_OFF = getattr(uiScriptLocale, "OPTION_OFF", "Off")
|
|
||||||
|
|
||||||
TEMPORARY_X = +13
|
TEMPORARY_X = +13
|
||||||
TEXT_TEMPORARY_X = -10
|
TEXT_TEMPORARY_X = -10
|
||||||
@@ -20,7 +15,7 @@ window = {
|
|||||||
"y" : 0,
|
"y" : 0,
|
||||||
|
|
||||||
"width" : 305,
|
"width" : 305,
|
||||||
"height" : 295,
|
"height" : 255,
|
||||||
|
|
||||||
"children" :
|
"children" :
|
||||||
(
|
(
|
||||||
@@ -32,7 +27,7 @@ window = {
|
|||||||
"y" : 0,
|
"y" : 0,
|
||||||
|
|
||||||
"width" : 305,
|
"width" : 305,
|
||||||
"height" : 295,
|
"height" : 255,
|
||||||
|
|
||||||
"children" :
|
"children" :
|
||||||
(
|
(
|
||||||
@@ -266,124 +261,6 @@ window = {
|
|||||||
"down_image" : ROOT_PATH + "middle_Button_03.sub",
|
"down_image" : ROOT_PATH + "middle_Button_03.sub",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
|
||||||
"name" : "render_fps_mode",
|
|
||||||
"type" : "text",
|
|
||||||
|
|
||||||
"x" : 18,
|
|
||||||
"y" : 210 + 2,
|
|
||||||
|
|
||||||
"text" : OPTION_RENDER_FPS,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name" : "render_fps_60",
|
|
||||||
"type" : "radio_button",
|
|
||||||
|
|
||||||
"x" : 82,
|
|
||||||
"y" : 210,
|
|
||||||
|
|
||||||
"text" : "60",
|
|
||||||
|
|
||||||
"default_image" : ROOT_PATH + "small_Button_01.sub",
|
|
||||||
"over_image" : ROOT_PATH + "small_Button_02.sub",
|
|
||||||
"down_image" : ROOT_PATH + "small_Button_03.sub",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name" : "render_fps_120",
|
|
||||||
"type" : "radio_button",
|
|
||||||
|
|
||||||
"x" : 124,
|
|
||||||
"y" : 210,
|
|
||||||
|
|
||||||
"text" : "120",
|
|
||||||
|
|
||||||
"default_image" : ROOT_PATH + "small_Button_01.sub",
|
|
||||||
"over_image" : ROOT_PATH + "small_Button_02.sub",
|
|
||||||
"down_image" : ROOT_PATH + "small_Button_03.sub",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name" : "render_fps_144",
|
|
||||||
"type" : "radio_button",
|
|
||||||
|
|
||||||
"x" : 166,
|
|
||||||
"y" : 210,
|
|
||||||
|
|
||||||
"text" : "144",
|
|
||||||
|
|
||||||
"default_image" : ROOT_PATH + "small_Button_01.sub",
|
|
||||||
"over_image" : ROOT_PATH + "small_Button_02.sub",
|
|
||||||
"down_image" : ROOT_PATH + "small_Button_03.sub",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name" : "render_fps_240",
|
|
||||||
"type" : "radio_button",
|
|
||||||
|
|
||||||
"x" : 208,
|
|
||||||
"y" : 210,
|
|
||||||
|
|
||||||
"text" : "240",
|
|
||||||
|
|
||||||
"default_image" : ROOT_PATH + "small_Button_01.sub",
|
|
||||||
"over_image" : ROOT_PATH + "small_Button_02.sub",
|
|
||||||
"down_image" : ROOT_PATH + "small_Button_03.sub",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name" : "render_fps_max",
|
|
||||||
"type" : "radio_button",
|
|
||||||
|
|
||||||
"x" : 250,
|
|
||||||
"y" : 210,
|
|
||||||
|
|
||||||
"text" : OPTION_RENDER_FPS_MAX,
|
|
||||||
|
|
||||||
"default_image" : ROOT_PATH + "small_Button_01.sub",
|
|
||||||
"over_image" : ROOT_PATH + "small_Button_02.sub",
|
|
||||||
"down_image" : ROOT_PATH + "small_Button_03.sub",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name" : "performance_hud_mode",
|
|
||||||
"type" : "text",
|
|
||||||
|
|
||||||
"x" : 18,
|
|
||||||
"y" : 235 + 2,
|
|
||||||
|
|
||||||
"text" : OPTION_PERFORMANCE_HUD,
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name" : "performance_hud_off",
|
|
||||||
"type" : "radio_button",
|
|
||||||
|
|
||||||
"x" : 110,
|
|
||||||
"y" : 235,
|
|
||||||
|
|
||||||
"text" : OPTION_OFF,
|
|
||||||
|
|
||||||
"default_image" : ROOT_PATH + "small_Button_01.sub",
|
|
||||||
"over_image" : ROOT_PATH + "small_Button_02.sub",
|
|
||||||
"down_image" : ROOT_PATH + "small_Button_03.sub",
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name" : "performance_hud_on",
|
|
||||||
"type" : "radio_button",
|
|
||||||
|
|
||||||
"x" : 160,
|
|
||||||
"y" : 235,
|
|
||||||
|
|
||||||
"text" : OPTION_ON,
|
|
||||||
|
|
||||||
"default_image" : ROOT_PATH + "small_Button_01.sub",
|
|
||||||
"over_image" : ROOT_PATH + "small_Button_02.sub",
|
|
||||||
"down_image" : ROOT_PATH + "small_Button_03.sub",
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
## 그림자
|
## 그림자
|
||||||
# {
|
# {
|
||||||
|
|||||||
@@ -163,14 +163,23 @@ Files under `.updates/` are created by the launcher. The user shouldn't touch th
|
|||||||
|
|
||||||
1. On a trusted machine (not random laptop), with the private signing key present:
|
1. On a trusted machine (not random laptop), with the private signing key present:
|
||||||
```bash
|
```bash
|
||||||
./scripts/make-release.sh --version 2026.04.14-1 --source /path/to/fresh/client
|
./scripts/make-release.sh --source /path/to/fresh/client --version 2026.04.14-1 \
|
||||||
|
--previous 2026.04.13-3 --notes notes.md --dry-run
|
||||||
```
|
```
|
||||||
2. The script walks the client directory, computes sha256 for each file, writes a `manifest.json`, signs it, and produces a release directory `release/2026.04.14-1/` containing the manifest, its signature, and only the new blobs (ones not already present on the server).
|
[`scripts/make-release.sh`](../scripts/make-release.sh) is the single entry
|
||||||
|
point for the v1 manual flow. It drives `make-manifest.py` + `sign-manifest.py`,
|
||||||
|
builds the content-addressed blob tree under `files/<hash[0:2]>/<hash>` with
|
||||||
|
hardlink-based deduplication, archives the signed manifest into
|
||||||
|
`manifests/<version>.json`, and — unless `--dry-run` is passed — rsyncs the
|
||||||
|
blob tree first and the `manifest.json` + `manifest.json.sig` pair last so the
|
||||||
|
release becomes visible atomically. Flags: `--key` (default
|
||||||
|
`~/.config/metin/launcher-signing-key`, must be mode 600), `--out` (default
|
||||||
|
`/tmp/release-<version>`), `--force` to overwrite a non-empty out dir, `--yes`
|
||||||
|
to skip the interactive rsync confirmation, `--rsync-target <user@host:/path>`
|
||||||
|
to override the upload destination.
|
||||||
|
2. The script walks the client directory, computes sha256 for each file, writes a `manifest.json`, signs it, and produces a release directory containing the manifest, its signature, and the deduplicated blob tree.
|
||||||
3. Human review: diff the new manifest against the previous one, sanity-check size and file count.
|
3. Human review: diff the new manifest against the previous one, sanity-check size and file count.
|
||||||
4. `rsync` the release directory to the VPS:
|
4. Re-run without `--dry-run` (same args) to rsync to the VPS. The script prints the target and waits for confirmation unless `--yes` is passed.
|
||||||
```bash
|
|
||||||
rsync -av release/2026.04.14-1/ mt2.jakubkadlec.dev@mt2.jakubkadlec.dev:/var/www/updates.jakubkadlec.dev/
|
|
||||||
```
|
|
||||||
5. Verify from a second machine: `curl` the manifest, check signature, check a random blob.
|
5. Verify from a second machine: `curl` the manifest, check signature, check a random blob.
|
||||||
6. Tag the release in git.
|
6. Tag the release in git.
|
||||||
|
|
||||||
|
|||||||
169
scripts/make-release.sh
Executable file
169
scripts/make-release.sh
Executable file
@@ -0,0 +1,169 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# make-release.sh — assemble, sign, and (optionally) publish a client release.
|
||||||
|
#
|
||||||
|
# Drives scripts/make-manifest.py + scripts/sign-manifest.py, then builds the
|
||||||
|
# content-addressed blob tree the launcher pulls from. See docs/update-manager.md
|
||||||
|
# for the end-to-end design; this script is the v1 manual publishing flow.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# scripts/make-release.sh --source <client-dir> --version <version> \
|
||||||
|
# [--previous <version>] [--notes <file>] \
|
||||||
|
# [--key <path>] [--out <path>] [--force] \
|
||||||
|
# [--dry-run] [--yes] [--rsync-target <user@host:/path>]
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# -------- arg parsing --------
|
||||||
|
SOURCE=""
|
||||||
|
VERSION=""
|
||||||
|
PREVIOUS=""
|
||||||
|
NOTES_FILE=""
|
||||||
|
KEY="${HOME}/.config/metin/launcher-signing-key"
|
||||||
|
OUT=""
|
||||||
|
FORCE=0
|
||||||
|
DRY_RUN=0
|
||||||
|
YES=0
|
||||||
|
RSYNC_TARGET="mt2.jakubkadlec.dev@mt2.jakubkadlec.dev:/var/www/updates.jakubkadlec.dev/"
|
||||||
|
|
||||||
|
die() { echo "error: $*" >&2; exit 1; }
|
||||||
|
say() { echo "[make-release] $*"; }
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--source) SOURCE="$2"; shift 2 ;;
|
||||||
|
--version) VERSION="$2"; shift 2 ;;
|
||||||
|
--previous) PREVIOUS="$2"; shift 2 ;;
|
||||||
|
--notes) NOTES_FILE="$2"; shift 2 ;;
|
||||||
|
--key) KEY="$2"; shift 2 ;;
|
||||||
|
--out) OUT="$2"; shift 2 ;;
|
||||||
|
--force) FORCE=1; shift ;;
|
||||||
|
--dry-run) DRY_RUN=1; shift ;;
|
||||||
|
--yes) YES=1; shift ;;
|
||||||
|
--rsync-target) RSYNC_TARGET="$2"; shift 2 ;;
|
||||||
|
-h|--help) sed -n '1,15p' "$0"; exit 0 ;;
|
||||||
|
*) die "unknown arg: $1" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ -n "$SOURCE" ]] || die "--source is required"
|
||||||
|
[[ -n "$VERSION" ]] || die "--version is required"
|
||||||
|
[[ -d "$SOURCE" ]] || die "source dir does not exist: $SOURCE"
|
||||||
|
[[ -f "$SOURCE/Metin2.exe" ]] || die "source does not look like a client dir (missing Metin2.exe): $SOURCE"
|
||||||
|
[[ -f "$KEY" ]] || die "signing key not found: $KEY"
|
||||||
|
|
||||||
|
KEY_MODE=$(stat -c '%a' "$KEY")
|
||||||
|
[[ "$KEY_MODE" == "600" ]] || die "signing key $KEY must be mode 600, got $KEY_MODE"
|
||||||
|
|
||||||
|
[[ -n "$NOTES_FILE" && ! -f "$NOTES_FILE" ]] && die "notes file not found: $NOTES_FILE"
|
||||||
|
|
||||||
|
: "${OUT:=/tmp/release-${VERSION}}"
|
||||||
|
SOURCE=$(cd "$SOURCE" && pwd)
|
||||||
|
OUT_ABS=$(mkdir -p "$OUT" && cd "$OUT" && pwd)
|
||||||
|
|
||||||
|
if [[ -n "$(ls -A "$OUT_ABS" 2>/dev/null)" && "$FORCE" -ne 1 ]]; then
|
||||||
|
die "output directory $OUT_ABS is non-empty (use --force to overwrite)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||||
|
|
||||||
|
say "source: $SOURCE"
|
||||||
|
say "version: $VERSION"
|
||||||
|
say "out: $OUT_ABS"
|
||||||
|
say "key: $KEY"
|
||||||
|
|
||||||
|
# -------- [1/6] manifest --------
|
||||||
|
say "[1/6] building manifest"
|
||||||
|
mkdir -p "$OUT_ABS/manifests" "$OUT_ABS/files"
|
||||||
|
MANIFEST="$OUT_ABS/manifest.json"
|
||||||
|
|
||||||
|
mk_args=(--source "$SOURCE" --version "$VERSION" --out "$MANIFEST")
|
||||||
|
[[ -n "$PREVIOUS" ]] && mk_args+=(--previous "$PREVIOUS")
|
||||||
|
if [[ -n "$NOTES_FILE" ]]; then
|
||||||
|
notes_text=$(cat "$NOTES_FILE")
|
||||||
|
mk_args+=(--notes "$notes_text")
|
||||||
|
fi
|
||||||
|
python3 "$SCRIPT_DIR/make-manifest.py" "${mk_args[@]}"
|
||||||
|
|
||||||
|
# -------- [2/6] sign --------
|
||||||
|
say "[2/6] signing manifest"
|
||||||
|
python3 "$SCRIPT_DIR/sign-manifest.py" --manifest "$MANIFEST" --key "$KEY"
|
||||||
|
SIG="$MANIFEST.sig"
|
||||||
|
[[ -f "$SIG" ]] || die "signature not produced"
|
||||||
|
sig_len=$(stat -c '%s' "$SIG")
|
||||||
|
[[ "$sig_len" == "64" ]] || die "signature is $sig_len bytes, expected 64"
|
||||||
|
|
||||||
|
# -------- [3/6] archive historical manifest --------
|
||||||
|
say "[3/6] archiving historical manifest -> manifests/${VERSION}.json"
|
||||||
|
cp -f "$MANIFEST" "$OUT_ABS/manifests/${VERSION}.json"
|
||||||
|
cp -f "$SIG" "$OUT_ABS/manifests/${VERSION}.json.sig"
|
||||||
|
|
||||||
|
# -------- [4/6] blob tree --------
|
||||||
|
say "[4/6] building content-addressed blob tree"
|
||||||
|
|
||||||
|
# Extract (path, sha256) pairs for launcher + every file entry.
|
||||||
|
mapfile -t PAIRS < <(jq -r '
|
||||||
|
([.launcher] + .files)
|
||||||
|
| .[]
|
||||||
|
| "\(.sha256)\t\(.path)"
|
||||||
|
' "$MANIFEST")
|
||||||
|
|
||||||
|
total_entries=${#PAIRS[@]}
|
||||||
|
unique_count=0
|
||||||
|
dedup_count=0
|
||||||
|
bytes_written=0
|
||||||
|
|
||||||
|
declare -A SEEN
|
||||||
|
for pair in "${PAIRS[@]}"; do
|
||||||
|
hash="${pair%%$'\t'*}"
|
||||||
|
rel="${pair#*$'\t'}"
|
||||||
|
src="$SOURCE/$rel"
|
||||||
|
[[ -f "$src" ]] || die "file in manifest missing from source: $rel"
|
||||||
|
if [[ -n "${SEEN[$hash]:-}" ]]; then
|
||||||
|
dedup_count=$((dedup_count + 1))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
SEEN[$hash]=1
|
||||||
|
unique_count=$((unique_count + 1))
|
||||||
|
prefix="${hash:0:2}"
|
||||||
|
dst_dir="$OUT_ABS/files/$prefix"
|
||||||
|
dst="$dst_dir/$hash"
|
||||||
|
mkdir -p "$dst_dir"
|
||||||
|
if [[ -f "$dst" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
# Try hardlink first, fall back to copy across filesystems.
|
||||||
|
if ! cp -l "$src" "$dst" 2>/dev/null; then
|
||||||
|
cp "$src" "$dst"
|
||||||
|
fi
|
||||||
|
sz=$(stat -c '%s' "$dst")
|
||||||
|
bytes_written=$((bytes_written + sz))
|
||||||
|
done
|
||||||
|
|
||||||
|
say " entries: $total_entries unique blobs: $unique_count deduped: $dedup_count"
|
||||||
|
say " bytes written: $bytes_written"
|
||||||
|
|
||||||
|
# -------- [5/6] layout summary --------
|
||||||
|
say "[5/6] final layout:"
|
||||||
|
(cd "$OUT_ABS" && find . -maxdepth 2 -mindepth 1 -printf ' %p\n' | sort | head -40)
|
||||||
|
|
||||||
|
# -------- [6/6] rsync --------
|
||||||
|
if [[ "$DRY_RUN" -eq 1 ]]; then
|
||||||
|
say "[6/6] --dry-run set, skipping rsync. target would be: $RSYNC_TARGET"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
say "[6/6] rsync target: $RSYNC_TARGET"
|
||||||
|
if [[ "$YES" -ne 1 ]]; then
|
||||||
|
read -r -p "continue? [y/N] " ans
|
||||||
|
[[ "$ans" == "y" || "$ans" == "Y" ]] || die "aborted by user"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Stage 1: everything except manifest.json(.sig) — blobs and historical archive.
|
||||||
|
rsync -av --delay-updates --checksum --omit-dir-times --no-perms \
|
||||||
|
--exclude 'manifest.json' --exclude 'manifest.json.sig' \
|
||||||
|
"$OUT_ABS"/ "$RSYNC_TARGET"
|
||||||
|
|
||||||
|
# Stage 2: manifest + signature, so the new release becomes visible last.
|
||||||
|
rsync -av --checksum --omit-dir-times --no-perms \
|
||||||
|
"$MANIFEST" "$SIG" "$RSYNC_TARGET"
|
||||||
|
|
||||||
|
say "done."
|
||||||
Reference in New Issue
Block a user