forked from metin-server/m2dev-client
Compare commits
15 Commits
claude/mak
...
issue-9-sa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
12df5a2bd6 | ||
|
|
09efcadbdd | ||
|
|
ecc99a8683 | ||
|
|
7871288b6d | ||
|
|
4ef859e26f | ||
|
|
c11008d1c8 | ||
|
|
a52debbb2a | ||
|
|
403dddd6af | ||
|
|
10915467c1 | ||
|
|
780900af61 | ||
|
|
b9065ca8d2 | ||
|
|
8767a2b3ac | ||
|
|
0edaea5993 | ||
|
|
5e79fc27e1 | ||
|
|
95fc2df7c0 |
@@ -1,524 +0,0 @@
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,654 +0,0 @@
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
assets/Effect/ymir work/effect/etc/compete/ready.dds
Normal file
BIN
assets/Effect/ymir work/effect/etc/compete/ready.dds
Normal file
Binary file not shown.
BIN
assets/Effect/ymir work/effect/monster2/smoke_dust.dds
Normal file
BIN
assets/Effect/ymir work/effect/monster2/smoke_dust.dds
Normal file
Binary file not shown.
@@ -1,5 +1,4 @@
|
||||
ScriptType MotionData
|
||||
|
||||
MotionFileName "D:\Ymir Work\monster\orc_lord\32_1.GR2"
|
||||
MotionFileName "D:\Ymir Work\monster\orc_lord\30_1.GR2"
|
||||
MotionDuration 0.833333
|
||||
|
||||
|
||||
BIN
assets/Sound/sound/common/walk_grass_n.wav
Normal file
BIN
assets/Sound/sound/common/walk_grass_n.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/bou/bou_swing1.wav
Normal file
BIN
assets/Sound/sound/monster/bou/bou_swing1.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/chuhen/club_attack.wav
Normal file
BIN
assets/Sound/sound/monster/chuhen/club_attack.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/gupae/gup_swing2.wav
Normal file
BIN
assets/Sound/sound/monster/gupae/gup_swing2.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/gupae/gup_swing3.wav
Normal file
BIN
assets/Sound/sound/monster/gupae/gup_swing3.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/maenghwan/mah_swing1.wav
Normal file
BIN
assets/Sound/sound/monster/maenghwan/mah_swing1.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/misterious_diseased_boss/damage_1.wav
Normal file
BIN
assets/Sound/sound/monster/misterious_diseased_boss/damage_1.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/thief1/th1_act2.wav
Normal file
BIN
assets/Sound/sound/monster/thief1/th1_act2.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/thief1/th1_swing2.wav
Normal file
BIN
assets/Sound/sound/monster/thief1/th1_swing2.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/thief1/th1_swing3.wav
Normal file
BIN
assets/Sound/sound/monster/thief1/th1_swing3.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/thief2/th2_swing2.wav
Normal file
BIN
assets/Sound/sound/monster/thief2/th2_swing2.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/thief2/th2_swing3.wav
Normal file
BIN
assets/Sound/sound/monster/thief2/th2_swing3.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/thiefboss1/thb1_swing2.wav
Normal file
BIN
assets/Sound/sound/monster/thiefboss1/thb1_swing2.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/thiefboss2/thb2_swing2.wav
Normal file
BIN
assets/Sound/sound/monster/thiefboss2/thb2_swing2.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/thiefboss2/thb2_swing3.wav
Normal file
BIN
assets/Sound/sound/monster/thiefboss2/thb2_swing3.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/monster/thiefboss3/thb3_swing2.wav
Normal file
BIN
assets/Sound/sound/monster/thiefboss3/thb3_swing2.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/pc/sura/general/attack_1.wav
Normal file
BIN
assets/Sound/sound/pc/sura/general/attack_1.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/pc/sura/general/attack_2.wav
Normal file
BIN
assets/Sound/sound/pc/sura/general/attack_2.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/pc/sura/general/attack_3.wav
Normal file
BIN
assets/Sound/sound/pc/sura/general/attack_3.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/pc/sura/general/swing_3.wav
Normal file
BIN
assets/Sound/sound/pc/sura/general/swing_3.wav
Normal file
Binary file not shown.
BIN
assets/Sound/sound/pc/sura/skill/horse_splash.wav
Normal file
BIN
assets/Sound/sound/pc/sura/skill/horse_splash.wav
Normal file
Binary file not shown.
Binary file not shown.
@@ -33,6 +33,9 @@ import uiAffectShower
|
||||
import uiPlayerGauge
|
||||
import uiCharacter
|
||||
import uiTarget
|
||||
import uiAutopickup
|
||||
import uiStoneQueue
|
||||
import uiSwitchbot
|
||||
|
||||
# PRIVATE_SHOP_PRICE_LIST
|
||||
import uiPrivateShopBuilder
|
||||
@@ -55,6 +58,157 @@ from _weakref import proxy
|
||||
SCREENSHOT_CWDSAVE = False
|
||||
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
|
||||
cameraPitch = 27.0
|
||||
cameraRotation = 0.0
|
||||
@@ -64,6 +218,7 @@ testAlignment = 0
|
||||
|
||||
class GameWindow(ui.ScriptWindow):
|
||||
def __init__(self, stream):
|
||||
_WriteHeadlessTrace("GameWindow.__init__ begin")
|
||||
ui.ScriptWindow.__init__(self, "GAME")
|
||||
self.SetWindowName("game")
|
||||
net.SetPhaseWindow(net.PHASE_WINDOW_GAME, self)
|
||||
@@ -72,6 +227,7 @@ class GameWindow(ui.ScriptWindow):
|
||||
self.quickSlotPageIndex = 0
|
||||
self.lastPKModeSendedTime = 0
|
||||
self.pressNumber = None
|
||||
self.headlessGmEnabled = _HeadlessGMEnabled()
|
||||
|
||||
self.guildWarQuestionDialog = None
|
||||
self.interface = None
|
||||
@@ -82,9 +238,16 @@ class GameWindow(ui.ScriptWindow):
|
||||
self.playerGauge = None
|
||||
|
||||
self.stream = stream
|
||||
self.interface = interfaceModule.Interface()
|
||||
self.interface.MakeInterface()
|
||||
self.interface.ShowDefaultWindows()
|
||||
if self.headlessGmEnabled:
|
||||
self.interface = _HeadlessInterface()
|
||||
_WriteHeadlessTrace("GameWindow.__init__ interface_headless")
|
||||
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.speed = 0.03
|
||||
@@ -112,6 +275,7 @@ class GameWindow(ui.ScriptWindow):
|
||||
|
||||
self.__ServerCommand_Build()
|
||||
self.__ProcessPreservedServerCommand()
|
||||
_WriteHeadlessTrace("GameWindow.__init__ done")
|
||||
|
||||
def __del__(self):
|
||||
player.SetGameWindow(0)
|
||||
@@ -133,6 +297,10 @@ class GameWindow(ui.ScriptWindow):
|
||||
self.enableXMasBoom = False
|
||||
self.startTimeXMasBoom = 0.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
|
||||
|
||||
@@ -220,6 +388,7 @@ class GameWindow(ui.ScriptWindow):
|
||||
self.currentCubeNPC = 0
|
||||
|
||||
def Close(self):
|
||||
_WriteHeadlessTrace("GameWindow.Close begin current_map=%s" % background.GetCurrentMapName())
|
||||
self.Hide()
|
||||
|
||||
global cameraDistance, cameraPitch, cameraRotation, cameraHeight
|
||||
@@ -298,6 +467,7 @@ class GameWindow(ui.ScriptWindow):
|
||||
app.HideCursor()
|
||||
|
||||
print("---------------------------------------------------------------------------- CLOSE GAME WINDOW")
|
||||
_WriteHeadlessTrace("GameWindow.Close end current_map=%s" % background.GetCurrentMapName())
|
||||
|
||||
def __BuildKeyDict(self):
|
||||
onPressKeyDict = {}
|
||||
@@ -856,6 +1026,7 @@ class GameWindow(ui.ScriptWindow):
|
||||
|
||||
# SHOW_LOCAL_MAP_NAME
|
||||
def ShowMapName(self, mapName, x, y):
|
||||
_WriteHeadlessTrace("ShowMapName map=%s x=%d y=%d" % (mapName, x, y))
|
||||
|
||||
if self.mapNameShower:
|
||||
self.mapNameShower.ShowMapName(mapName, x, y)
|
||||
@@ -1465,8 +1636,104 @@ class GameWindow(ui.ScriptWindow):
|
||||
def OnMouseMiddleButtonUp(self):
|
||||
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):
|
||||
app.UpdateGame()
|
||||
self.__HeadlessGMOnUpdate()
|
||||
|
||||
if self.mapNameShower.IsShow():
|
||||
self.mapNameShower.Update()
|
||||
@@ -1913,6 +2180,10 @@ class GameWindow(ui.ScriptWindow):
|
||||
"PartyRequestDenied" : self.__PartyRequestDenied,
|
||||
"horse_state" : self.__Horse_UpdateState,
|
||||
"hide_horse_state" : self.__Horse_HideState,
|
||||
"AutoPickupState" : self.__AutoPickupState,
|
||||
"StoneQueueState" : self.__StoneQueueState,
|
||||
"SwitchbotState" : self.__SwitchbotState,
|
||||
"SwitchbotSlot" : self.__SwitchbotSlot,
|
||||
"WarUC" : self.__GuildWar_UpdateMemberCount,
|
||||
"test_server" : self.__EnableTestServerFlag,
|
||||
"mall" : self.__InGameShop_Show,
|
||||
@@ -1960,6 +2231,18 @@ class GameWindow(ui.ScriptWindow):
|
||||
def PartyHealReady(self):
|
||||
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):
|
||||
self.interface.AskSafeboxPassword()
|
||||
|
||||
@@ -2229,4 +2512,3 @@ class GameWindow(ui.ScriptWindow):
|
||||
|
||||
def SkillClearCoolTime(self, slotIndex):
|
||||
self.interface.SkillClearCoolTime(slotIndex)
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ import uiSystem
|
||||
import uiRestart
|
||||
import uiToolTip
|
||||
import uiMiniMap
|
||||
import uiBiolog
|
||||
import uiTeleport
|
||||
import uiSwitchbot
|
||||
import uiParty
|
||||
import uiSafebox
|
||||
import uiGuild
|
||||
@@ -75,6 +78,9 @@ class Interface(object):
|
||||
self.wndChat = None
|
||||
self.wndMessenger = None
|
||||
self.wndMiniMap = None
|
||||
self.wndBiolog = None
|
||||
self.wndTeleport = None
|
||||
self.wndSwitchbot = None
|
||||
self.wndGuild = None
|
||||
self.wndGuildBuilding = None
|
||||
|
||||
@@ -180,6 +186,9 @@ class Interface(object):
|
||||
wndDragonSoulRefine = None
|
||||
|
||||
wndMiniMap = uiMiniMap.MiniMap()
|
||||
wndBiolog = uiBiolog.BiologWindow()
|
||||
wndTeleport = uiTeleport.TeleportWindow()
|
||||
wndSwitchbot = uiSwitchbot.SwitchbotWindow()
|
||||
wndSafebox = uiSafebox.SafeboxWindow()
|
||||
|
||||
# ITEM_MALL
|
||||
@@ -195,8 +204,14 @@ class Interface(object):
|
||||
self.wndDragonSoul = wndDragonSoul
|
||||
self.wndDragonSoulRefine = wndDragonSoulRefine
|
||||
self.wndMiniMap = wndMiniMap
|
||||
self.wndBiolog = wndBiolog
|
||||
self.wndTeleport = wndTeleport
|
||||
self.wndSwitchbot = wndSwitchbot
|
||||
self.wndSafebox = wndSafebox
|
||||
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:
|
||||
self.wndDragonSoul.SetDragonSoulRefineWindow(self.wndDragonSoulRefine)
|
||||
@@ -409,6 +424,11 @@ class Interface(object):
|
||||
if self.wndMiniMap:
|
||||
self.wndMiniMap.Destroy()
|
||||
|
||||
if self.wndBiolog:
|
||||
self.wndBiolog.Hide()
|
||||
if self.wndSwitchbot:
|
||||
self.wndSwitchbot.Hide()
|
||||
|
||||
if self.wndSafebox:
|
||||
self.wndSafebox.Destroy()
|
||||
|
||||
@@ -499,6 +519,8 @@ class Interface(object):
|
||||
del self.tooltipItem
|
||||
del self.tooltipSkill
|
||||
del self.wndMiniMap
|
||||
del self.wndBiolog
|
||||
del self.wndSwitchbot
|
||||
del self.wndSafebox
|
||||
del self.wndMall
|
||||
del self.wndParty
|
||||
@@ -858,6 +880,9 @@ class Interface(object):
|
||||
if self.wndMiniMap:
|
||||
self.wndMiniMap.Hide()
|
||||
|
||||
if self.wndBiolog:
|
||||
self.wndBiolog.Hide()
|
||||
|
||||
if self.wndMessenger:
|
||||
self.wndMessenger.Hide()
|
||||
|
||||
@@ -942,6 +967,33 @@ class Interface(object):
|
||||
def MiniMapScaleDown(self):
|
||||
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):
|
||||
if False == player.IsObserverMode():
|
||||
if False == self.wndCharacter.IsShow():
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import os
|
||||
|
||||
import ui
|
||||
import uiScriptLocale
|
||||
import net
|
||||
@@ -35,6 +37,25 @@ import uiOption
|
||||
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):
|
||||
def __init__(self, stream):
|
||||
print("NEW LOADING WINDOW -------------------------------------------------------------------------------")
|
||||
@@ -218,6 +239,7 @@ class LoadingWindow(ui.ScriptWindow):
|
||||
try:
|
||||
runFunc()
|
||||
except:
|
||||
_WriteHeadlessTrace("LoadData failure step=%d" % progress)
|
||||
self.errMsg.Show()
|
||||
self.loadStepList=[]
|
||||
|
||||
@@ -302,7 +324,9 @@ class LoadingWindow(ui.ScriptWindow):
|
||||
emotion.RegisterEmotionIcons()
|
||||
|
||||
def __LoadMap(self):
|
||||
_WriteHeadlessTrace("LoadMap begin global_x=%d global_y=%d" % (self.playerX, self.playerY))
|
||||
net.Warp(self.playerX, self.playerY)
|
||||
_WriteHeadlessTrace("LoadMap current_map=%s" % background.GetCurrentMapName())
|
||||
|
||||
def __LoadSound(self):
|
||||
playerSettingModule.LoadGameData("SOUND")
|
||||
@@ -337,6 +361,7 @@ class LoadingWindow(ui.ScriptWindow):
|
||||
# END_OF_GUILD_BUILDING
|
||||
|
||||
def __StartGame(self):
|
||||
_WriteHeadlessTrace("StartGame begin current_map=%s" % background.GetCurrentMapName())
|
||||
background.SetViewDistanceSet(background.DISTANCE0, 25600)
|
||||
"""
|
||||
background.SetViewDistanceSet(background.DISTANCE1, 19200)
|
||||
@@ -349,6 +374,7 @@ class LoadingWindow(ui.ScriptWindow):
|
||||
app.SetGlobalCenterPosition(self.playerX, self.playerY)
|
||||
|
||||
net.StartGame()
|
||||
_WriteHeadlessTrace("StartGame queued current_map=%s" % background.GetCurrentMapName())
|
||||
|
||||
def _ReloadTitleNames():
|
||||
for i in range(len(localeInfo.TITLE_NAME_LIST)):
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import os
|
||||
import dbg
|
||||
import app
|
||||
import net
|
||||
@@ -18,6 +19,10 @@ import ime
|
||||
import uiScriptLocale
|
||||
import debugInfo
|
||||
|
||||
|
||||
def _AllowHeadlessLoginInfo():
|
||||
return os.environ.get("M2_HEADLESS_SCENARIO", "").strip().lower() == "gm_teleport"
|
||||
|
||||
# Multi-language hot-reload system
|
||||
from uilocaleselector import LocaleSelector
|
||||
|
||||
@@ -715,7 +720,7 @@ class LoginWindow(ui.ScriptWindow):
|
||||
|
||||
def __LoadLoginInfo(self, loginInfoFileName):
|
||||
# This should not work in production
|
||||
if not debugInfo.IsDebugMode():
|
||||
if not debugInfo.IsDebugMode() and not _AllowHeadlessLoginInfo():
|
||||
app.loggined = FALSE
|
||||
else:
|
||||
try:
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
###################################################################################################
|
||||
# Network
|
||||
|
||||
import os
|
||||
|
||||
import app
|
||||
import chr
|
||||
import dbg
|
||||
@@ -18,6 +20,25 @@ import uiPhaseCurtain
|
||||
|
||||
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):
|
||||
# MR-15: Multiline dialog messages
|
||||
BASE_HEIGHT = 105
|
||||
@@ -167,6 +188,7 @@ class MainStream(object):
|
||||
|
||||
if newPhaseWindow:
|
||||
newPhaseWindow.Open()
|
||||
_WriteHeadlessTrace("MainStream.ChangePhase opened=%s" % newPhaseWindow.__class__.__name__)
|
||||
|
||||
self.curPhaseWindow=newPhaseWindow
|
||||
|
||||
@@ -237,7 +259,7 @@ class MainStream(object):
|
||||
try:
|
||||
import introLoading
|
||||
loadingPhaseWindow=introLoading.LoadingWindow(self)
|
||||
loadingPhaseWindow.LoadData(x, y)
|
||||
loadingPhaseWindow.DEBUG_LoadData(x, y)
|
||||
self.SetPhaseWindow(loadingPhaseWindow)
|
||||
except:
|
||||
import exception
|
||||
@@ -256,8 +278,10 @@ class MainStream(object):
|
||||
def SetGamePhase(self):
|
||||
try:
|
||||
import game
|
||||
_WriteHeadlessTrace("MainStream.SetGamePhase begin current_map=%s" % background.GetCurrentMapName())
|
||||
self.popupWindow.Close()
|
||||
self.SetPhaseWindow(game.GameWindow(self))
|
||||
_WriteHeadlessTrace("MainStream.SetGamePhase queued current_map=%s" % background.GetCurrentMapName())
|
||||
except:
|
||||
raise
|
||||
import exception
|
||||
|
||||
@@ -659,6 +659,7 @@ def __LoadGameWarriorEx(race, path):
|
||||
|
||||
## Bone
|
||||
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON, "equip_right_hand")
|
||||
chrmgr.RegisterAttachingBoneName(chr.PART_ACCE, "Bip01 Spine2")
|
||||
|
||||
def __LoadGameAssassinEx(race, path):
|
||||
## Assassin
|
||||
@@ -872,6 +873,7 @@ def __LoadGameAssassinEx(race, path):
|
||||
|
||||
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON, "equip_right")
|
||||
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON_LEFT, "equip_left")
|
||||
chrmgr.RegisterAttachingBoneName(chr.PART_ACCE, "Bip01 Spine2")
|
||||
|
||||
def __LoadGameSuraEx(race, path):
|
||||
## Sura
|
||||
@@ -1189,6 +1191,7 @@ def __LoadGameShamanEx(race, path):
|
||||
|
||||
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON, "equip_right")
|
||||
chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON_LEFT, "equip_left")
|
||||
chrmgr.RegisterAttachingBoneName(chr.PART_ACCE, "Bip01 Spine2")
|
||||
|
||||
|
||||
def __LoadGameSkill():
|
||||
@@ -1456,4 +1459,4 @@ def SetGuildBuilding(race, name, grade):
|
||||
chrmgr.SetPathName("d:/ymir work/guild/building/%s/" % name)
|
||||
chrmgr.LoadRaceData("%s%02d.msm" % (name, grade))
|
||||
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,3 +1,5 @@
|
||||
import os
|
||||
|
||||
import dbg
|
||||
import app
|
||||
import localeInfo
|
||||
@@ -14,6 +16,66 @@ import stringCommander
|
||||
|
||||
#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():
|
||||
musicInfo.LoadLastPlayFieldMusic()
|
||||
|
||||
@@ -36,6 +98,7 @@ def RunApp():
|
||||
return
|
||||
|
||||
app.SetCamera(1500.0, 30.0, 0.0, 180.0)
|
||||
_ApplyRenderFPSOverride()
|
||||
|
||||
#Gets and sets the floating-point control word
|
||||
#app.SetControlFP()
|
||||
@@ -47,8 +110,7 @@ def RunApp():
|
||||
mainStream.Create()
|
||||
|
||||
#mainStream.SetLoadingPhase()
|
||||
|
||||
mainStream.SetLoginPhase()
|
||||
_SetInitialPhase(mainStream)
|
||||
#mainStream.SetSelectCharacterPhase()
|
||||
#mainStream.SetCreateCharacterPhase()
|
||||
#mainStream.SetSelectEmpirePhase()
|
||||
@@ -58,4 +120,3 @@ def RunApp():
|
||||
mainStream.Destroy()
|
||||
|
||||
RunApp()
|
||||
|
||||
|
||||
145
assets/root/uiAutopickup.py
Normal file
145
assets/root/uiAutopickup.py
Normal file
@@ -0,0 +1,145 @@
|
||||
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)
|
||||
145
assets/root/uiBiolog.py
Normal file
145
assets/root/uiBiolog.py
Normal file
@@ -0,0 +1,145 @@
|
||||
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()
|
||||
233
assets/root/uiStoneQueue.py
Normal file
233
assets/root/uiStoneQueue.py
Normal file
@@ -0,0 +1,233 @@
|
||||
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()
|
||||
455
assets/root/uiSwitchbot.py
Normal file
455
assets/root/uiSwitchbot.py
Normal file
@@ -0,0 +1,455 @@
|
||||
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)
|
||||
173
assets/root/uiTeleport.py
Normal file
173
assets/root/uiTeleport.py
Normal file
@@ -0,0 +1,173 @@
|
||||
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,6 +8,7 @@ import localeInfo
|
||||
import constInfo
|
||||
import chrmgr
|
||||
import player
|
||||
import uiAutopickup
|
||||
import uiPrivateShopBuilder # 占쏙옙占쏙옙호
|
||||
import interfaceModule # 占쏙옙占쏙옙호
|
||||
|
||||
@@ -39,8 +40,14 @@ class OptionDialog(ui.ScriptWindow):
|
||||
self.alwaysShowNameButtonList = []
|
||||
self.showDamageButtonList = []
|
||||
self.showsalesTextButtonList = []
|
||||
self.autoPickupButton = None
|
||||
self.autoPickupDialog = None
|
||||
|
||||
def Destroy(self):
|
||||
if self.autoPickupDialog:
|
||||
self.autoPickupDialog.Destroy()
|
||||
self.autoPickupDialog = None
|
||||
|
||||
self.ClearDictionary()
|
||||
|
||||
self.__Initialize()
|
||||
@@ -80,6 +87,7 @@ class OptionDialog(ui.ScriptWindow):
|
||||
self.showDamageButtonList.append(GetObject("show_damage_off_button"))
|
||||
self.showsalesTextButtonList.append(GetObject("salestext_on_button"))
|
||||
self.showsalesTextButtonList.append(GetObject("salestext_off_button"))
|
||||
self.autoPickupButton = GetObject("autopickup_button")
|
||||
|
||||
except:
|
||||
import exception
|
||||
@@ -130,6 +138,7 @@ class OptionDialog(ui.ScriptWindow):
|
||||
|
||||
self.showsalesTextButtonList[0].SAFE_SetEvent(self.__OnClickSalesTextOnButton)
|
||||
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.viewTargetBoardButtonList, constInfo.GET_VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD())
|
||||
@@ -241,6 +250,15 @@ class OptionDialog(ui.ScriptWindow):
|
||||
def __OnClickSalesTextOffButton(self):
|
||||
systemSetting.SetShowSalesTextFlag(False)
|
||||
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):
|
||||
if player.GetStatus(player.LEVEL)<constInfo.PVPMODE_PROTECTED_LEVEL:
|
||||
|
||||
@@ -11,6 +11,7 @@ import grp
|
||||
import uiScriptLocale
|
||||
import uiRefine
|
||||
import uiAttachMetin
|
||||
import uiStoneQueue
|
||||
import uiPickMoney
|
||||
import uiCommon
|
||||
import uiPrivateShopBuilder # Prevent ItemMove while private shop is open
|
||||
@@ -23,6 +24,12 @@ ITEM_FLAG_APPLICABLE = 1 << 14
|
||||
|
||||
class CostumeWindow(ui.ScriptWindow):
|
||||
|
||||
SLOT_ORDER = (
|
||||
item.COSTUME_SLOT_BODY,
|
||||
item.COSTUME_SLOT_HAIR,
|
||||
item.COSTUME_SLOT_SASH,
|
||||
)
|
||||
|
||||
def __init__(self, wndInventory):
|
||||
import exception
|
||||
|
||||
@@ -87,8 +94,7 @@ class CostumeWindow(ui.ScriptWindow):
|
||||
def RefreshCostumeSlot(self):
|
||||
getItemVNum=player.GetItemIndex
|
||||
|
||||
for i in range(item.COSTUME_SLOT_COUNT):
|
||||
slotNumber = item.COSTUME_SLOT_START + i
|
||||
for slotNumber in self.SLOT_ORDER:
|
||||
self.wndEquip.SetItemSlot(slotNumber, getItemVNum(slotNumber), 0)
|
||||
|
||||
self.wndEquip.RefreshSlot()
|
||||
@@ -251,11 +257,13 @@ class InventoryWindow(ui.ScriptWindow):
|
||||
isLoaded = 0
|
||||
isOpenedCostumeWindowWhenClosingInventory = 0 # Whether costume window was open when closing inventory
|
||||
isOpenedBeltWindowWhenClosingInventory = 0 # Whether belt inventory was open when closing inventory
|
||||
sashAbsorbSlot = -1
|
||||
|
||||
def __init__(self):
|
||||
ui.ScriptWindow.__init__(self)
|
||||
|
||||
self.isOpenedBeltWindowWhenClosingInventory = 0 # Whether belt inventory was open when closing inventory
|
||||
self.sashAbsorbSlot = -1
|
||||
|
||||
self.__LoadWindow()
|
||||
|
||||
@@ -357,6 +365,10 @@ class InventoryWindow(ui.ScriptWindow):
|
||||
self.attachMetinDialog = uiAttachMetin.AttachMetinDialog()
|
||||
self.attachMetinDialog.Hide()
|
||||
|
||||
## StoneQueueDialog
|
||||
self.stoneQueueDialog = uiStoneQueue.StoneQueueWindow()
|
||||
self.stoneQueueDialog.Hide()
|
||||
|
||||
## MoneySlot
|
||||
self.wndMoneySlot.SetEvent(ui.__mem_func__(self.OpenPickMoneyDialog))
|
||||
|
||||
@@ -407,6 +419,9 @@ class InventoryWindow(ui.ScriptWindow):
|
||||
self.attachMetinDialog.Destroy()
|
||||
self.attachMetinDialog = 0
|
||||
|
||||
self.stoneQueueDialog.Destroy()
|
||||
self.stoneQueueDialog = 0
|
||||
|
||||
self.tooltipItem = None
|
||||
self.wndItem = 0
|
||||
self.wndEquip = 0
|
||||
@@ -431,6 +446,7 @@ class InventoryWindow(ui.ScriptWindow):
|
||||
self.equipmentTab = []
|
||||
|
||||
def Hide(self):
|
||||
self.__AbortSashAbsorb(False)
|
||||
if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS():
|
||||
self.OnCloseQuestionDialog()
|
||||
return
|
||||
@@ -455,6 +471,91 @@ class InventoryWindow(ui.ScriptWindow):
|
||||
def Close(self):
|
||||
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):
|
||||
self.inventoryPageIndex = page
|
||||
self.inventoryTab[1-page].SetUp()
|
||||
@@ -701,6 +802,18 @@ class InventoryWindow(ui.ScriptWindow):
|
||||
|
||||
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():
|
||||
attachedSlotType = mouseModule.mouseController.GetAttachedType()
|
||||
attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber()
|
||||
@@ -841,20 +954,6 @@ class InventoryWindow(ui.ScriptWindow):
|
||||
scrollIndex = player.GetItemIndex(scrollSlotPos)
|
||||
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)
|
||||
|
||||
if player.REFINE_ALREADY_MAX_SOCKET_COUNT == result:
|
||||
@@ -879,7 +978,12 @@ class InventoryWindow(ui.ScriptWindow):
|
||||
if player.REFINE_OK != result:
|
||||
return
|
||||
|
||||
self.refineDialog.Open(scrollSlotPos, targetSlotPos)
|
||||
item.SelectItem(targetIndex)
|
||||
if item.GetItemType() == item.ITEM_TYPE_METIN:
|
||||
self.stoneQueueDialog.Open(scrollSlotPos, targetSlotPos)
|
||||
return
|
||||
|
||||
self.__SendUseItemToItemPacket(scrollSlotPos, targetSlotPos)
|
||||
|
||||
def DetachMetinFromItem(self, scrollSlotPos, targetSlotPos):
|
||||
scrollIndex = player.GetItemIndex(scrollSlotPos)
|
||||
@@ -1206,6 +1310,11 @@ class InventoryWindow(ui.ScriptWindow):
|
||||
def __UseItem(self, slotIndex):
|
||||
ItemVNum = player.GetItemIndex(slotIndex)
|
||||
item.SelectItem(ItemVNum)
|
||||
|
||||
if self.__IsSashItem(slotIndex):
|
||||
self.__BeginSashAbsorb(slotIndex)
|
||||
return
|
||||
|
||||
if item.IsFlag(item.ITEM_FLAG_CONFIRM_WHEN_USE):
|
||||
self.questionDialog = uiCommon.QuestionDialog()
|
||||
self.questionDialog.SetText(localeInfo.INVENTORY_REALLY_USE_ITEM)
|
||||
|
||||
@@ -222,6 +222,15 @@ class MiniMap(ui.ScriptWindow):
|
||||
self.tooltipAtlasOpen = MapTextToolTip()
|
||||
self.tooltipAtlasOpen.SetText(localeInfo.MINIMAP_SHOW_AREAMAP)
|
||||
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.Show()
|
||||
|
||||
@@ -259,12 +268,21 @@ class MiniMap(ui.ScriptWindow):
|
||||
self.MiniMapHideButton = 0
|
||||
self.MiniMapShowButton = 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.tooltipMiniMapClose = 0
|
||||
self.tooltipScaleUp = 0
|
||||
self.tooltipScaleDown = 0
|
||||
self.tooltipAtlasOpen = 0
|
||||
self.tooltipBiolog = 0
|
||||
self.tooltipTeleport = 0
|
||||
self.tooltipSwitchbot = 0
|
||||
self.tooltipInfo = None
|
||||
self.serverInfo = None
|
||||
|
||||
@@ -346,6 +364,39 @@ class MiniMap(ui.ScriptWindow):
|
||||
if miniMap.IsAtlas():
|
||||
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()
|
||||
self.tooltipMiniMapOpen.SetTooltipPosition(ButtonPosX, ButtonPosY)
|
||||
|
||||
@@ -361,6 +412,15 @@ class MiniMap(ui.ScriptWindow):
|
||||
(ButtonPosX, ButtonPosY) = self.AtlasShowButton.GetGlobalPosition()
|
||||
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()
|
||||
|
||||
def Destroy(self):
|
||||
@@ -441,6 +501,21 @@ class MiniMap(ui.ScriptWindow):
|
||||
else:
|
||||
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):
|
||||
(x, y) = self.GetGlobalPosition()
|
||||
fx = float(x)
|
||||
@@ -485,3 +560,18 @@ class MiniMap(ui.ScriptWindow):
|
||||
self.AtlasWindow.Hide()
|
||||
else:
|
||||
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)
|
||||
ui.Gauge.Hide(self)
|
||||
|
||||
def OnUpdate(self):
|
||||
def __UpdateScreenPosition(self):
|
||||
playerIndex = player.GetMainCharacterIndex()
|
||||
|
||||
(x, y, z)=textTail.GetPosition(playerIndex)
|
||||
@@ -30,6 +30,14 @@ class PlayerGauge(ui.Gauge):
|
||||
isChat = textTail.IsChat(playerIndex)
|
||||
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):
|
||||
|
||||
self.curHP = player.GetStatus(player.HP)
|
||||
|
||||
@@ -94,24 +94,32 @@ class PrivateShopAdvertisementBoard(ui.ThinBoard):
|
||||
net.SendOnClickPacket(self.vid)
|
||||
|
||||
return True
|
||||
|
||||
def OnUpdate(self):
|
||||
|
||||
def __UpdateProjectedPosition(self):
|
||||
if not self.vid:
|
||||
return
|
||||
|
||||
projectVID = None
|
||||
if systemSetting.IsShowSalesText():
|
||||
self.Show()
|
||||
x, y = chr.GetProjectPosition(self.vid, 220)
|
||||
self.SetPosition(x - self.GetWidth()/2, y - self.GetHeight()/2)
|
||||
projectVID = self.vid
|
||||
elif player.GetMainCharacterIndex() == self.vid:
|
||||
projectVID = player.GetMainCharacterIndex()
|
||||
|
||||
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)
|
||||
|
||||
else:
|
||||
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.
|
||||
g_privateShopAdvertisementBoardDict[key].Show()
|
||||
x, y = chr.GetProjectPosition(player.GetMainCharacterIndex(), 220)
|
||||
g_privateShopAdvertisementBoardDict[key].SetPosition(x - self.GetWidth()/2, y - self.GetHeight()/2)
|
||||
else:
|
||||
g_privateShopAdvertisementBoardDict[key].Hide()
|
||||
def OnUpdate(self):
|
||||
self.__UpdateProjectedPosition()
|
||||
|
||||
def OnRender(self):
|
||||
# Keep the board anchored to the interpolated render position instead
|
||||
# of the legacy fixed update cadence.
|
||||
self.__UpdateProjectedPosition()
|
||||
|
||||
class PrivateShopBuilder(ui.ScriptWindow):
|
||||
|
||||
|
||||
@@ -41,6 +41,9 @@ class OptionDialog(ui.ScriptWindow):
|
||||
self.cameraModeButtonList = []
|
||||
self.fogModeButtonList = []
|
||||
self.tilingModeButtonList = []
|
||||
self.renderFPSButtonList = []
|
||||
self.renderFPSValues = [60, 120, 144, 240, 0]
|
||||
self.performanceHUDButtonList = []
|
||||
self.ctrlShadowQuality = 0
|
||||
|
||||
def Destroy(self):
|
||||
@@ -72,6 +75,13 @@ class OptionDialog(ui.ScriptWindow):
|
||||
self.fogModeButtonList.append(GetObject("fog_level2"))
|
||||
self.tilingModeButtonList.append(GetObject("tiling_cpu"))
|
||||
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.ctrlShadowQuality = GetObject("shadow_bar")
|
||||
except:
|
||||
@@ -106,6 +116,13 @@ class OptionDialog(ui.ScriptWindow):
|
||||
|
||||
self.tilingModeButtonList[0].SAFE_SetEvent(self.__OnClickTilingModeCPUButton)
|
||||
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)
|
||||
|
||||
@@ -115,6 +132,7 @@ class OptionDialog(ui.ScriptWindow):
|
||||
self.__ClickRadioButton(self.fogModeButtonList, systemSetting.GetFogLevel())
|
||||
# MR-14: -- END OF -- Fog update by Alaric
|
||||
self.__ClickRadioButton(self.cameraModeButtonList, constInfo.GET_CAMERA_MAX_DISTANCE_INDEX())
|
||||
self.RefreshRenderSettings()
|
||||
|
||||
if musicInfo.fieldMusic==musicInfo.METIN2THEMA:
|
||||
self.selectMusicFile.SetText(uiSelectMusic.DEFAULT_THEMA)
|
||||
@@ -179,6 +197,41 @@ class OptionDialog(ui.ScriptWindow):
|
||||
|
||||
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):
|
||||
self.__SetCameraMode(0)
|
||||
|
||||
@@ -194,6 +247,27 @@ class OptionDialog(ui.ScriptWindow):
|
||||
def __OnClickFogModeLevel2Button(self):
|
||||
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):
|
||||
self.selectMusicFile.SetText(fileName[:MUSIC_FILENAME_MAX_LEN])
|
||||
|
||||
@@ -239,6 +313,8 @@ class OptionDialog(ui.ScriptWindow):
|
||||
return True
|
||||
|
||||
def Show(self):
|
||||
self.RefreshRenderSettings()
|
||||
self.__SetCurTilingMode()
|
||||
ui.ScriptWindow.Show(self)
|
||||
|
||||
def Close(self):
|
||||
|
||||
@@ -1021,12 +1021,14 @@ class ItemToolTip(ToolTip):
|
||||
isCostumeItem = 0
|
||||
isCostumeHair = 0
|
||||
isCostumeBody = 0
|
||||
isCostumeSash = 0
|
||||
|
||||
if app.ENABLE_COSTUME_SYSTEM:
|
||||
if item.ITEM_TYPE_COSTUME == itemType:
|
||||
isCostumeItem = 1
|
||||
isCostumeHair = item.COSTUME_TYPE_HAIR == itemSubType
|
||||
isCostumeBody = item.COSTUME_TYPE_BODY == itemSubType
|
||||
isCostumeSash = item.COSTUME_TYPE_SASH == itemSubType
|
||||
|
||||
#dbg.TraceError("IS_COSTUME_ITEM! body(%d) hair(%d)" % (isCostumeBody, isCostumeHair))
|
||||
|
||||
@@ -1124,6 +1126,15 @@ class ItemToolTip(ToolTip):
|
||||
self.__AppendAttributeInformation(attrSlot)
|
||||
|
||||
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
|
||||
for i in range(item.LIMIT_MAX_NUM):
|
||||
|
||||
BIN
assets/sound2/sound/monster2/outlaw/fall.wav
Normal file
BIN
assets/sound2/sound/monster2/outlaw/fall.wav
Normal file
Binary file not shown.
BIN
assets/sound2/sound/pc2/assassin/bow/attack1.wav
Normal file
BIN
assets/sound2/sound/pc2/assassin/bow/attack1.wav
Normal file
Binary file not shown.
@@ -1,5 +1,5 @@
|
||||
ScriptType CharacterSoundInformation
|
||||
|
||||
SoundDataCount 2
|
||||
SoundData00 0.066000 "sound/pc2/assassin/dualhand_sword/combo7.wav"
|
||||
SoundData01 0.033000 "sound/common/swing/w_1h_c_2.wav"
|
||||
SoundData00 0.231000 "sound/pc2/assassin/dualhand_sword/combo4.wav"
|
||||
SoundData01 0.198000 "sound/common/swing/a_dh_c_4.wav"
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import uiScriptLocale
|
||||
import item
|
||||
|
||||
COSTUME_START_INDEX = item.COSTUME_SLOT_START
|
||||
|
||||
window = {
|
||||
"name" : "CostumeWindow",
|
||||
|
||||
@@ -71,9 +69,9 @@ window = {
|
||||
"height" : 145,
|
||||
|
||||
"slot" : (
|
||||
{"index":COSTUME_START_INDEX+0, "x":61, "y":45, "width":32, "height":64},
|
||||
{"index":COSTUME_START_INDEX+1, "x":61, "y": 8, "width":32, "height":32},
|
||||
{"index":COSTUME_START_INDEX+2, "x":5, "y":145, "width":32, "height":32},
|
||||
{"index":item.COSTUME_SLOT_BODY, "x":61, "y":45, "width":32, "height":64},
|
||||
{"index":item.COSTUME_SLOT_HAIR, "x":61, "y": 8, "width":32, "height":32},
|
||||
{"index":item.COSTUME_SLOT_SASH, "x":5, "y":145, "width":32, "height":32},
|
||||
),
|
||||
},
|
||||
),
|
||||
|
||||
@@ -69,6 +69,7 @@ window = {
|
||||
##{"index":22, "x":75, "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,
|
||||
|
||||
"width" : 300,
|
||||
"height" : 25*11+8,
|
||||
"height" : 25*12+8,
|
||||
|
||||
"children" :
|
||||
(
|
||||
@@ -32,7 +32,7 @@ window = {
|
||||
"y" : 0,
|
||||
|
||||
"width" : 300,
|
||||
"height" : 25*11+8,
|
||||
"height" : 25*12+8,
|
||||
|
||||
"children" :
|
||||
(
|
||||
@@ -433,7 +433,29 @@ window = {
|
||||
"default_image" : ROOT_PATH + "middle_button_01.sub",
|
||||
"over_image" : ROOT_PATH + "middle_button_02.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,6 +1,11 @@
|
||||
import uiScriptLocale
|
||||
|
||||
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
|
||||
TEXT_TEMPORARY_X = -10
|
||||
@@ -15,7 +20,7 @@ window = {
|
||||
"y" : 0,
|
||||
|
||||
"width" : 305,
|
||||
"height" : 255,
|
||||
"height" : 295,
|
||||
|
||||
"children" :
|
||||
(
|
||||
@@ -27,7 +32,7 @@ window = {
|
||||
"y" : 0,
|
||||
|
||||
"width" : 305,
|
||||
"height" : 255,
|
||||
"height" : 295,
|
||||
|
||||
"children" :
|
||||
(
|
||||
@@ -261,6 +266,124 @@ window = {
|
||||
"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",
|
||||
},
|
||||
|
||||
|
||||
## 그림자
|
||||
# {
|
||||
|
||||
Reference in New Issue
Block a user