mirror of
https://github.com/genxium/DelayNoMore
synced 2024-12-26 03:39:00 +00:00
A temp broken commit except for OfflineMap - drafted basic cancellable skills.
This commit is contained in:
parent
8b80117d3d
commit
325dbfb79c
File diff suppressed because one or more lines are too long
@ -3,7 +3,7 @@
|
||||
"_name": "Atk1",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_duration": 0.36666666666666664,
|
||||
"_duration": 0.2833333333333333,
|
||||
"sample": 60,
|
||||
"speed": 1,
|
||||
"wrapMode": 1,
|
||||
@ -18,25 +18,25 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.03333333333333333,
|
||||
"frame": 0.05,
|
||||
"value": {
|
||||
"__uuid__": "12b90556-58b9-4311-b5d9-820fb76d659b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.11666666666666667,
|
||||
"frame": 0.1,
|
||||
"value": {
|
||||
"__uuid__": "72bc74a1-6e8c-48bb-9ab2-9b8f502ceffb"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.31666666666666665,
|
||||
"frame": 0.25,
|
||||
"value": {
|
||||
"__uuid__": "7e619896-100d-4903-b256-e30ddb5ad397"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.35,
|
||||
"frame": 0.26666666666666666,
|
||||
"value": {
|
||||
"__uuid__": "4a35e0f5-95c4-445b-8f9b-6514a060a72d"
|
||||
}
|
||||
|
79
frontend/assets/resources/animation/MonkGirl/Atk2.anim
Normal file
79
frontend/assets/resources/animation/MonkGirl/Atk2.anim
Normal file
@ -0,0 +1,79 @@
|
||||
{
|
||||
"__type__": "cc.AnimationClip",
|
||||
"_name": "Atk2",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_duration": 0.6,
|
||||
"sample": 60,
|
||||
"speed": 1,
|
||||
"wrapMode": 1,
|
||||
"curveData": {
|
||||
"comps": {
|
||||
"cc.Sprite": {
|
||||
"spriteFrame": [
|
||||
{
|
||||
"frame": 0,
|
||||
"value": {
|
||||
"__uuid__": "0e3b6c28-f265-457d-b000-aeea66d05428"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.03333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "1d9c010b-3209-4672-9f78-96527d62f4e0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.08333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "1fd3ca4d-ec4d-4858-a3d2-fe274e22d4be"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.11666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "b0aaf216-b8d7-4247-be61-df9f3146ce46"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.15,
|
||||
"value": {
|
||||
"__uuid__": "f12c5713-540f-4874-a6b0-0162f0ffb544"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.2,
|
||||
"value": {
|
||||
"__uuid__": "b9a4cd85-53d1-4280-bc9e-35a8dd482fa4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.23333333333333334,
|
||||
"value": {
|
||||
"__uuid__": "74e9fcd1-11dc-478e-b90a-d4c5cf551aad"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.3,
|
||||
"value": {
|
||||
"__uuid__": "e6c3bdcd-9ba8-4c5b-910d-2d93d9068abd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5166666666666667,
|
||||
"value": {
|
||||
"__uuid__": "c359790f-bbd1-4869-a37b-7f1c0bd91578"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5833333333333334,
|
||||
"value": {
|
||||
"__uuid__": "1b9074dd-d0b0-4129-8d72-8f356bf7f68c"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": []
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"ver": "2.1.0",
|
||||
"uuid": "e6e1d62a-de7d-4fe7-858c-2d2725b7c2e8",
|
||||
"subMetas": {}
|
||||
}
|
85
frontend/assets/resources/animation/MonkGirl/Atk3.anim
Normal file
85
frontend/assets/resources/animation/MonkGirl/Atk3.anim
Normal file
@ -0,0 +1,85 @@
|
||||
{
|
||||
"__type__": "cc.AnimationClip",
|
||||
"_name": "Atk3",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_duration": 1,
|
||||
"sample": 60,
|
||||
"speed": 1,
|
||||
"wrapMode": 1,
|
||||
"curveData": {
|
||||
"comps": {
|
||||
"cc.Sprite": {
|
||||
"spriteFrame": [
|
||||
{
|
||||
"frame": 0,
|
||||
"value": {
|
||||
"__uuid__": "4e1a3e61-dc3e-4de1-9385-bce2c5f54764"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.05,
|
||||
"value": {
|
||||
"__uuid__": "39ba4413-6f4a-49a5-a7ca-d11140dfe7dd"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.11666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "26b646c7-bdbc-495e-adaf-9d52ef1b5c84"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.21666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "5a5208a0-1c29-446f-8375-739aef09fe65"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.3,
|
||||
"value": {
|
||||
"__uuid__": "414628f0-13ec-4f01-83a0-b94f6a13fff1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.43333333333333335,
|
||||
"value": {
|
||||
"__uuid__": "c494965a-e7e6-4c99-ac61-60642e6247dc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.5666666666666667,
|
||||
"value": {
|
||||
"__uuid__": "04cafb17-39ab-4f2b-9830-3eaf42cab254"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.7166666666666667,
|
||||
"value": {
|
||||
"__uuid__": "fd9c7d8a-1038-4cab-a0e6-699e404701db"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.8333333333333334,
|
||||
"value": {
|
||||
"__uuid__": "2447c6b3-292b-43b4-84e5-acc35df0c1f5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.9333333333333333,
|
||||
"value": {
|
||||
"__uuid__": "00275818-b9b6-41ab-a792-f21ff10747fa"
|
||||
}
|
||||
},
|
||||
{
|
||||
"frame": 0.9833333333333333,
|
||||
"value": {
|
||||
"__uuid__": "11a06f33-cdfa-46cf-aae4-41e72a6711c2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": []
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"ver": "2.1.0",
|
||||
"uuid": "e8247e2a-1b5b-4618-86f8-224b25246b55",
|
||||
"subMetas": {}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 93 KiB |
@ -9,10 +9,10 @@
|
||||
</data>
|
||||
</layer>
|
||||
<objectgroup id="1" name="PlayerStartingPos">
|
||||
<object id="135" x="901" y="1579">
|
||||
<object id="135" x="865" y="1447">
|
||||
<point/>
|
||||
</object>
|
||||
<object id="137" x="861" y="1540">
|
||||
<object id="137" x="909" y="1447">
|
||||
<point/>
|
||||
</object>
|
||||
</objectgroup>
|
||||
|
@ -933,7 +933,7 @@
|
||||
"__id__": 11
|
||||
},
|
||||
"_children": [],
|
||||
"_active": false,
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 23
|
||||
@ -1034,6 +1034,12 @@
|
||||
},
|
||||
{
|
||||
"__uuid__": "7cb4d395-c68f-4643-9e2e-8cb8e200d3a5"
|
||||
},
|
||||
{
|
||||
"__uuid__": "e6e1d62a-de7d-4fe7-858c-2d2725b7c2e8"
|
||||
},
|
||||
{
|
||||
"__uuid__": "e8247e2a-1b5b-4618-86f8-224b25246b55"
|
||||
}
|
||||
],
|
||||
"playOnLoad": false,
|
||||
|
@ -12,6 +12,8 @@ window.ATK_CHARACTER_STATE = {
|
||||
BlownUp1: [8, "BlownUp1"],
|
||||
LayDown1: [9, "LayDown1"],
|
||||
GetUp1: [10, "GetUp1"],
|
||||
Atk2: [11, "Atk2"],
|
||||
Atk3: [12, "Atk3"],
|
||||
};
|
||||
|
||||
window.ATK_CHARACTER_STATE_ARR = [];
|
||||
|
@ -586,13 +586,13 @@ cc.Class({
|
||||
const jsPlayersArr = new Array().fill(null);
|
||||
for (let k in pbRdf.playersArr) {
|
||||
const pbPlayer = pbRdf.playersArr[k];
|
||||
const jsPlayer = gopkgs.NewPlayerDownsyncJs(pbPlayer.id, pbPlayer.virtualGridX, pbPlayer.virtualGridY, pbPlayer.dirX, pbPlayer.dirY, pbPlayer.velX, pbPlayer.velY, pbPlayer.framesToRecover, pbPlayer.framesInChState, pbPlayer.speed, pbPlayer.battleState, pbPlayer.characterState, pbPlayer.joinIndex, pbPlayer.hp, pbPlayer.maxHp, pbPlayer.inAir, pbPlayer.colliderRadius);
|
||||
const jsPlayer = gopkgs.NewPlayerDownsyncJs(pbPlayer.id, pbPlayer.virtualGridX, pbPlayer.virtualGridY, pbPlayer.dirX, pbPlayer.dirY, pbPlayer.velX, pbPlayer.velY, pbPlayer.framesToRecover, pbPlayer.framesInChState, pbPlayer.speed, pbPlayer.battleState, pbPlayer.characterState, pbPlayer.joinIndex, pbPlayer.hp, pbPlayer.maxHp, pbPlayer.colliderRadius, pbPlayer.inAir);
|
||||
jsPlayersArr[k] = jsPlayer;
|
||||
}
|
||||
const jsMeleeBulletsArr = [];
|
||||
for (let k in pbRdf.meleeBullets) {
|
||||
const pbBullet = pbRdf.meleeBullets[k];
|
||||
const jsBullet = gopkgs.NewMeleeBulletJs(pbBullet.originatedRenderFrameId, pbBullet.offenderJoinIndex, pbBullet.startupFrames, pbBullet.cancellableStFrame, pbBullet.cancellableEdFrame, pbBullet.activeFrames, pbBullet.hitStunFrames, pbBullet.blockStunFrames, pbBullet.pushbackX, pbBullet.pushbackY, pbBullet.damage, pbBullet.selfLockVelX, pbBullet.selfLockVelY, pbBullet.hitboxOffsetX, pbBullet.hitboxOffsetY, pbBullet.hitboxSizeX, pbBullet.hitboxSizeY, pbBullet.blowUp);
|
||||
const jsBullet = gopkgs.NewMeleeBulletJs(pbBullet.originatedRenderFrameId, pbBullet.offenderJoinIndex, pbBullet.startupFrames, pbBullet.cancellableStFrame, pbBullet.cancellableEdFrame, pbBullet.activeFrames, pbBullet.hitStunFrames, pbBullet.blockStunFrames, pbBullet.pushbackVelX, pbBullet.pushbackVelY, pbBullet.damage, pbBullet.selfLockVelX, pbBullet.selfLockVelY, pbBullet.hitboxOffsetX, pbBullet.hitboxOffsetY, pbBullet.hitboxSizeX, pbBullet.hitboxSizeY, pbBullet.blowUp);
|
||||
jsMeleeBulletsArr.push(jsBullet);
|
||||
}
|
||||
|
||||
@ -832,12 +832,17 @@ batchInputFrameIdRange=[${batch[0].inputFrameId}, ${batch[batch.length - 1].inpu
|
||||
const chConfig = self.chConfigsOrderedByJoinIndex[joinIndex - 1];
|
||||
playerScriptIns.setSpecies(chConfig.SpeciesName);
|
||||
|
||||
if (1 == joinIndex) {
|
||||
newPlayerNode.color = cc.Color.RED;
|
||||
} else {
|
||||
newPlayerNode.color = cc.Color.BLUE;
|
||||
}
|
||||
|
||||
const [wx, wy] = gopkgs.VirtualGridToWorldPos(vx, vy);
|
||||
newPlayerNode.setPosition(wx, wy);
|
||||
playerScriptIns.mapNode = self.node;
|
||||
const colliderRadius = playerDownsyncInfo.ColliderRadius;
|
||||
const halfColliderWidth = colliderRadius,
|
||||
halfColliderHeight = colliderRadius + colliderRadius; // avoid multiplying
|
||||
const [halfColliderWidth, halfColliderHeight] = gopkgs.VirtualGridToWorldPos(colliderRadius, colliderRadius + colliderRadius); // avoid multiplying
|
||||
const colliderWidth = halfColliderWidth + halfColliderWidth,
|
||||
colliderHeight = halfColliderHeight + halfColliderHeight; // avoid multiplying
|
||||
|
||||
@ -846,7 +851,7 @@ batchInputFrameIdRange=[${batch[0].inputFrameId}, ${batch[batch.length - 1].inpu
|
||||
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||
self.gopkgsCollisionSysMap[collisionPlayerIndex] = newPlayerCollider;
|
||||
|
||||
console.log(`Created new player collider: joinIndex=${joinIndex}, colliderRadius=${playerDownsyncInfo.ColliderRadius}`);
|
||||
console.log(`Created new player collider: joinIndex=${joinIndex}`);
|
||||
|
||||
safelyAddChild(self.node, newPlayerNode);
|
||||
setLocalZOrder(newPlayerNode, 5);
|
||||
|
@ -123,7 +123,9 @@ cc.Class({
|
||||
}
|
||||
|
||||
const p1Vpos = gopkgs.WorldToVirtualGridPos(boundaryObjs.playerStartingPositions[0].x, boundaryObjs.playerStartingPositions[0].y);
|
||||
const p2Vpos = gopkgs.WorldToVirtualGridPos(boundaryObjs.playerStartingPositions[1].x, boundaryObjs.playerStartingPositions[1].y);
|
||||
const speedV = gopkgs.WorldToVirtualGridPos(1.0, 0);
|
||||
const colliderRadiusV = gopkgs.WorldToVirtualGridPos(12.0, 0);
|
||||
|
||||
const startRdf = window.pb.protos.RoomDownsyncFrame.create({
|
||||
id: window.MAGIC_ROOM_DOWNSYNC_FRAME_ID.BATTLE_START,
|
||||
@ -134,17 +136,32 @@ cc.Class({
|
||||
virtualGridX: p1Vpos[0],
|
||||
virtualGridY: p1Vpos[1],
|
||||
speed: speedV[0],
|
||||
colliderRadius: 12,
|
||||
colliderRadius: colliderRadiusV[0],
|
||||
characterState: window.ATK_CHARACTER_STATE.InAirIdle1NoJump[0],
|
||||
framesToRecover: 0,
|
||||
dirX: 0,
|
||||
dirX: +2,
|
||||
dirY: 0,
|
||||
velX: 0,
|
||||
velY: 0,
|
||||
inAir: true,
|
||||
}),
|
||||
window.pb.protos.PlayerDownsync.create({
|
||||
id: 11,
|
||||
joinIndex: 2,
|
||||
virtualGridX: p2Vpos[0],
|
||||
virtualGridY: p2Vpos[1],
|
||||
speed: speedV[0],
|
||||
colliderRadius: colliderRadiusV[0],
|
||||
characterState: window.ATK_CHARACTER_STATE.InAirIdle1NoJump[0],
|
||||
framesToRecover: 0,
|
||||
dirX: -2,
|
||||
dirY: 0,
|
||||
velX: 0,
|
||||
velY: 0,
|
||||
inAir: true,
|
||||
}),
|
||||
],
|
||||
speciesIdList: [0],
|
||||
speciesIdList: [0, 0],
|
||||
});
|
||||
|
||||
self.selfPlayerInfo = {
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
|
||||
const (
|
||||
MAX_FLOAT64 = 1.7e+308
|
||||
MAX_INT32 = int32(999999999)
|
||||
COLLISION_PLAYER_INDEX_PREFIX = (1 << 17)
|
||||
COLLISION_BARRIER_INDEX_PREFIX = (1 << 16)
|
||||
COLLISION_BULLET_INDEX_PREFIX = (1 << 15)
|
||||
@ -26,6 +27,9 @@ const (
|
||||
|
||||
SNAP_INTO_PLATFORM_OVERLAP = float64(0.1)
|
||||
SNAP_INTO_PLATFORM_THRESHOLD = float64(0.5)
|
||||
|
||||
NO_SKILL = int32(-1)
|
||||
NO_SKILL_HIT = int32(-1)
|
||||
)
|
||||
|
||||
// These directions are chosen such that when speed is changed to "(speedX+delta, speedY+delta)" for any of them, the direction is unchanged.
|
||||
@ -53,6 +57,9 @@ const (
|
||||
ATK_CHARACTER_STATE_BLOWN_UP1 = int32(8)
|
||||
ATK_CHARACTER_STATE_LAY_DOWN1 = int32(9)
|
||||
ATK_CHARACTER_STATE_GET_UP1 = int32(10)
|
||||
|
||||
ATK_CHARACTER_STATE_ATK2 = int32(11)
|
||||
ATK_CHARACTER_STATE_ATK3 = int32(12)
|
||||
)
|
||||
|
||||
var inAirSet = map[int32]bool{
|
||||
@ -63,6 +70,22 @@ var inAirSet = map[int32]bool{
|
||||
ATK_CHARACTER_STATE_BLOWN_UP1: true,
|
||||
}
|
||||
|
||||
var noOpSet = map[int32]bool{
|
||||
ATK_CHARACTER_STATE_ATKED1: true,
|
||||
ATK_CHARACTER_STATE_INAIR_ATKED1: true,
|
||||
ATK_CHARACTER_STATE_BLOWN_UP1: true,
|
||||
ATK_CHARACTER_STATE_LAY_DOWN1: true,
|
||||
// During the invinsible frames of GET_UP1, the player is allowed to take any action
|
||||
}
|
||||
|
||||
var invinsibleSet = map[int32]bool{
|
||||
ATK_CHARACTER_STATE_BLOWN_UP1: true,
|
||||
ATK_CHARACTER_STATE_LAY_DOWN1: true,
|
||||
ATK_CHARACTER_STATE_GET_UP1: true,
|
||||
}
|
||||
|
||||
var nonAttackingSet = map[int32]bool{}
|
||||
|
||||
func ConvertToInputFrameId(renderFrameId int32, inputDelayFrames int32, inputScaleFrames uint32) int32 {
|
||||
if renderFrameId < inputDelayFrames {
|
||||
return 0
|
||||
@ -329,6 +352,10 @@ func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync,
|
||||
return PATTERN_ID_UNABLE_TO_OP, false, 0, 0
|
||||
}
|
||||
|
||||
if _, existent := noOpSet[currPlayerDownsync.CharacterState]; existent {
|
||||
return PATTERN_ID_UNABLE_TO_OP, false, 0, 0
|
||||
}
|
||||
|
||||
delayedInputList := inputsBuffer.GetByFrameId(delayedInputFrameId).(*InputFrameDownsync).InputList
|
||||
var delayedInputListForPrevRdf []uint64 = nil
|
||||
if 0 < delayedInputFrameIdForPrevRdf {
|
||||
@ -337,11 +364,8 @@ func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync,
|
||||
|
||||
jumpedOrNot := false
|
||||
joinIndex := currPlayerDownsync.JoinIndex
|
||||
if 0 < currPlayerDownsync.FramesToRecover {
|
||||
return PATTERN_ID_UNABLE_TO_OP, false, 0, 0
|
||||
}
|
||||
decodedInput := decodeInput(delayedInputList[joinIndex-1])
|
||||
effDx, effDy := decodedInput.Dx, decodedInput.Dy
|
||||
effDx, effDy := int32(0), int32(0)
|
||||
prevBtnALevel, prevBtnBLevel := int32(0), int32(0)
|
||||
if nil != delayedInputListForPrevRdf {
|
||||
prevDecodedInput := decodeInput(delayedInputListForPrevRdf[joinIndex-1])
|
||||
@ -349,20 +373,40 @@ func deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame *PlayerDownsync,
|
||||
prevBtnBLevel = prevDecodedInput.BtnBLevel
|
||||
}
|
||||
|
||||
if 0 == currPlayerDownsync.FramesToRecover {
|
||||
// Jumping and moving are only allowed here
|
||||
effDx, effDy = decodedInput.Dx, decodedInput.Dy
|
||||
if decodedInput.BtnBLevel > prevBtnBLevel {
|
||||
if _, existent := inAirSet[currPlayerDownsync.CharacterState]; !existent {
|
||||
jumpedOrNot = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
As long as the current "CharacterState" is not in "noOpSet", we have 2 cases where attacking is allowed:
|
||||
1. it happens when the player is IDLE or Walking, i.e. "0 == currPlayerDownsync.FramesToRecover", which is just the normal case
|
||||
2. it happens when the player is having non-empty "ActiveSkillId" which might be cancellable
|
||||
*/
|
||||
patternId := PATTERN_ID_NO_OP
|
||||
if decodedInput.BtnALevel > prevBtnALevel {
|
||||
if currPlayerDownsync.InAir {
|
||||
patternId = 1
|
||||
patternId = 255
|
||||
} else {
|
||||
patternId = 0
|
||||
patternId = 1
|
||||
}
|
||||
}
|
||||
|
||||
if PATTERN_ID_NO_OP != patternId && 0 < currPlayerDownsync.FramesToRecover {
|
||||
// [WARN] Handle skill cancellation
|
||||
patternId = PATTERN_ID_NO_OP // First, reset the patternId to no-op as it should be by default not cancelling anything
|
||||
skillConfig := skills[int(currPlayerDownsync.ActiveSkillId)]
|
||||
switch v := skillConfig.Hits[currPlayerDownsync.ActiveSkillHit].(type) {
|
||||
case *MeleeBullet:
|
||||
if v.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.CancellableEdFrame {
|
||||
patternId = int(currPlayerDownsync.ActiveSkillId + 1) // if "currPlayerDownsync.InAir", it won't map to a valid skill in the next step and thus act as PATTERN_ID_NO_OP
|
||||
}
|
||||
}
|
||||
effDx, effDy = 0, 0 // Most patterns/skills should not allow simultaneous movement
|
||||
}
|
||||
|
||||
return patternId, jumpedOrNot, effDx, effDy
|
||||
@ -394,6 +438,8 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
|
||||
MaxHp: currPlayerDownsync.MaxHp,
|
||||
FramesToRecover: currPlayerDownsync.FramesToRecover - 1,
|
||||
FramesInChState: currPlayerDownsync.FramesInChState + 1,
|
||||
ActiveSkillId: currPlayerDownsync.ActiveSkillId,
|
||||
ActiveSkillHit: currPlayerDownsync.ActiveSkillHit,
|
||||
}
|
||||
if nextRenderFramePlayers[i].FramesToRecover < 0 {
|
||||
nextRenderFramePlayers[i].FramesToRecover = 0
|
||||
@ -411,9 +457,6 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
|
||||
chConfig := chConfigsOrderedByJoinIndex[i]
|
||||
thatPlayerInNextFrame := nextRenderFramePlayers[i]
|
||||
patternId, jumpedOrNot, effDx, effDy := deriveOpPattern(currPlayerDownsync, thatPlayerInNextFrame, currRenderFrame, inputsBuffer, INPUT_DELAY_FRAMES, INPUT_SCALE_FRAMES)
|
||||
if PATTERN_ID_UNABLE_TO_OP == patternId {
|
||||
continue
|
||||
}
|
||||
|
||||
if jumpedOrNot {
|
||||
thatPlayerInNextFrame.VelY = int32(chConfig.JumpingInitVelY)
|
||||
@ -423,8 +466,13 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
|
||||
if PATTERN_ID_NO_OP != patternId {
|
||||
if skillId, existent := chConfig.PatternIdToSkillId[patternId]; existent {
|
||||
skillConfig := skills[skillId]
|
||||
thatPlayerInNextFrame.ActiveSkillId = int32(skillId)
|
||||
thatPlayerInNextFrame.ActiveSkillHit = 0
|
||||
|
||||
// TODO: Respect non-zero "selfLockVel"
|
||||
|
||||
// Hardcoded to use only the first hit for now
|
||||
switch v := skillConfig.Hits[0].(type) {
|
||||
switch v := skillConfig.Hits[thatPlayerInNextFrame.ActiveSkillHit].(type) {
|
||||
case *MeleeBullet:
|
||||
var newBullet MeleeBullet = *v // Copied primitive fields into an onstack variable
|
||||
newBullet.OriginatedRenderFrameId = currRenderFrame.Id
|
||||
@ -432,14 +480,24 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
|
||||
nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, &newBullet)
|
||||
thatPlayerInNextFrame.FramesToRecover = skillConfig.RecoveryFrames
|
||||
}
|
||||
|
||||
// TODO: How to differentiate skill cancellable among different characters, e.g. some characters might be allowed to have 4-cancellation-combo or more?
|
||||
switch skillId {
|
||||
case 1:
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATK1
|
||||
case 2:
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATK2
|
||||
case 3:
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATK3
|
||||
}
|
||||
if false == currPlayerDownsync.InAir {
|
||||
thatPlayerInNextFrame.VelX = 0
|
||||
}
|
||||
continue // Don't allow movement if skill is used
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if 0 == currPlayerDownsync.FramesToRecover {
|
||||
if 0 != effDx || 0 != effDy {
|
||||
thatPlayerInNextFrame.DirX, thatPlayerInNextFrame.DirY = effDx, effDy
|
||||
thatPlayerInNextFrame.VelX = effDx * currPlayerDownsync.Speed
|
||||
@ -449,6 +507,7 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
|
||||
thatPlayerInNextFrame.VelX = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Process player movement
|
||||
for i, currPlayerDownsync := range currRenderFrame.PlayersArr {
|
||||
@ -597,29 +656,21 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
|
||||
if v.OffenderJoinIndex == t.JoinIndex {
|
||||
continue
|
||||
}
|
||||
if _, existent := invinsibleSet[t.CharacterState]; existent {
|
||||
continue
|
||||
}
|
||||
overlapped, _, _, _ := CalcPushbacks(0, 0, bulletShape, defenderShape)
|
||||
if !overlapped {
|
||||
continue
|
||||
}
|
||||
joinIndex := t.JoinIndex
|
||||
xfac := int32(1) // By now, straight Punch offset doesn't respect "y-axis"
|
||||
if 0 > offender.DirX {
|
||||
xfac = -xfac
|
||||
}
|
||||
pushbackX, pushbackY := VirtualGridToWorldPos(-xfac*v.PushbackX, v.PushbackY)
|
||||
|
||||
for _, hardPushbackNorm := range *hardPushbackNorms[joinIndex-1] {
|
||||
projectedMagnitude := pushbackX*hardPushbackNorm.X + pushbackY*hardPushbackNorm.Y
|
||||
if 0 > projectedMagnitude {
|
||||
//fmt.Printf("defenderPlayerId=%d, joinIndex=%d reducing bullet pushback={%.3f, %.3f} by {%.3f, %.3f} where hardPushbackNorm={%.3f, %.3f}, projectedMagnitude=%.3f at renderFrame.id=%d", t.Id, joinIndex, pushbackX, pushbackY, projectedMagnitude*hardPushbackNorm.X, projectedMagnitude*hardPushbackNorm.Y, hardPushbackNorm.X, hardPushbackNorm.Y, projectedMagnitude, currRenderFrame.Id)
|
||||
pushbackX -= projectedMagnitude * hardPushbackNorm.X
|
||||
pushbackY -= projectedMagnitude * hardPushbackNorm.Y
|
||||
}
|
||||
}
|
||||
|
||||
effPushbacks[joinIndex-1].X += pushbackX
|
||||
effPushbacks[joinIndex-1].Y += pushbackY
|
||||
pushbackVelX, pushbackVelY := xfac*v.PushbackVelX, v.PushbackVelY
|
||||
atkedPlayerInNextFrame := nextRenderFramePlayers[t.JoinIndex-1]
|
||||
atkedPlayerInNextFrame.VelX = pushbackVelX
|
||||
atkedPlayerInNextFrame.VelY = pushbackVelY
|
||||
if v.BlowUp {
|
||||
atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_BLOWN_UP1
|
||||
} else {
|
||||
@ -656,13 +707,22 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
|
||||
}
|
||||
case ATK_CHARACTER_STATE_ATK1:
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_INAIR_ATK1
|
||||
// No inAir transition for ATK2/ATK3 for now
|
||||
case ATK_CHARACTER_STATE_ATKED1:
|
||||
thatPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_INAIR_ATKED1
|
||||
}
|
||||
}
|
||||
|
||||
// Reset "FramesInChState" if "CharacterState" is changed
|
||||
if thatPlayerInNextFrame.CharacterState != currPlayerDownsync.CharacterState {
|
||||
thatPlayerInNextFrame.FramesInChState = 0
|
||||
}
|
||||
|
||||
// Remove any active skill if not attacking
|
||||
if _, existent := nonAttackingSet[thatPlayerInNextFrame.CharacterState]; existent {
|
||||
thatPlayerInNextFrame.ActiveSkillId = NO_SKILL
|
||||
thatPlayerInNextFrame.ActiveSkillHit = NO_SKILL_HIT
|
||||
}
|
||||
}
|
||||
|
||||
return &RoomDownsyncFrame{
|
||||
|
@ -35,37 +35,91 @@ var Characters = map[int]*CharacterConfig{
|
||||
JumpingInitVelY: int32(float64(8) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
|
||||
PatternIdToSkillId: map[int]int{
|
||||
0: 1, // Atk1
|
||||
1: 2, // InAirAtk1
|
||||
1: 1, // Atk1
|
||||
2: 2, // Atk2
|
||||
3: 3, // Atk3
|
||||
255: 255, // InAirAtk1
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var skills = map[int]*Skill{
|
||||
1: &Skill{
|
||||
RecoveryFrames: int32(34),
|
||||
RecoveryFramesOnBlock: int32(34),
|
||||
RecoveryFramesOnHit: int32(34),
|
||||
RecoveryFrames: int32(20),
|
||||
RecoveryFramesOnBlock: int32(20),
|
||||
RecoveryFramesOnHit: int32(20),
|
||||
ReleaseTriggerType: int32(1),
|
||||
Hits: []interface{}{
|
||||
&MeleeBullet{
|
||||
Bullet: Bullet{
|
||||
StartupFrames: int32(5),
|
||||
ActiveFrames: int32(10),
|
||||
HitStunFrames: int32(18),
|
||||
HitStunFrames: int32(13),
|
||||
BlockStunFrames: int32(9),
|
||||
Damage: int32(5),
|
||||
PushbackX: int32(float64(8) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
PushbackY: int32(0),
|
||||
PushbackVelX: int32(float64(0.5) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
PushbackVelY: int32(0),
|
||||
HitboxOffsetX: int32(float64(12) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
HitboxOffsetY: int32(0),
|
||||
HitboxSizeX: int32(float64(24) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
HitboxSizeY: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
CancellableStFrame: int32(8),
|
||||
CancellableEdFrame: int32(20),
|
||||
// TODO: Use non-zero "selfLockVel"
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
2: &Skill{
|
||||
RecoveryFrames: int32(36),
|
||||
RecoveryFramesOnBlock: int32(36),
|
||||
RecoveryFramesOnHit: int32(36),
|
||||
ReleaseTriggerType: int32(1),
|
||||
Hits: []interface{}{
|
||||
&MeleeBullet{
|
||||
Bullet: Bullet{
|
||||
StartupFrames: int32(3),
|
||||
ActiveFrames: int32(20),
|
||||
HitStunFrames: int32(18),
|
||||
BlockStunFrames: int32(9),
|
||||
Damage: int32(5),
|
||||
PushbackVelX: int32(float64(0.5) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
PushbackVelY: int32(0),
|
||||
HitboxOffsetX: int32(float64(18) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
HitboxOffsetY: int32(0),
|
||||
HitboxSizeX: int32(float64(24) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
HitboxSizeY: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
CancellableStFrame: int32(18),
|
||||
CancellableEdFrame: int32(36),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
3: &Skill{
|
||||
RecoveryFrames: int32(60),
|
||||
RecoveryFramesOnBlock: int32(60),
|
||||
RecoveryFramesOnHit: int32(60),
|
||||
ReleaseTriggerType: int32(1),
|
||||
Hits: []interface{}{
|
||||
&MeleeBullet{
|
||||
Bullet: Bullet{
|
||||
StartupFrames: int32(1),
|
||||
ActiveFrames: int32(30),
|
||||
HitStunFrames: MAX_INT32,
|
||||
BlockStunFrames: int32(9),
|
||||
Damage: int32(10),
|
||||
PushbackVelX: int32(float64(1) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
PushbackVelY: int32(float64(4) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
HitboxOffsetX: int32(float64(24) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
HitboxOffsetY: int32(0),
|
||||
HitboxSizeX: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
HitboxSizeY: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
BlowUp: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
255: &Skill{
|
||||
RecoveryFrames: int32(34),
|
||||
RecoveryFramesOnBlock: int32(34),
|
||||
RecoveryFramesOnHit: int32(34),
|
||||
@ -78,8 +132,8 @@ var skills = map[int]*Skill{
|
||||
HitStunFrames: int32(18),
|
||||
BlockStunFrames: int32(9),
|
||||
Damage: int32(5),
|
||||
PushbackX: int32(float64(6) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
PushbackY: int32(0),
|
||||
PushbackVelX: int32(float64(0.5) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
PushbackVelY: int32(0),
|
||||
HitboxOffsetX: int32(float64(12) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
HitboxOffsetY: int32(0),
|
||||
HitboxSizeX: int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
|
||||
|
@ -23,7 +23,7 @@ type PlayerDownsync struct {
|
||||
Speed int32
|
||||
BattleState int32
|
||||
JoinIndex int32
|
||||
ColliderRadius float64
|
||||
ColliderRadius int32
|
||||
Removed bool
|
||||
Score int32
|
||||
LastMoveGmtMillis int32
|
||||
@ -33,6 +33,9 @@ type PlayerDownsync struct {
|
||||
MaxHp int32
|
||||
CharacterState int32
|
||||
InAir bool
|
||||
|
||||
ActiveSkillId int32
|
||||
ActiveSkillHit int32
|
||||
}
|
||||
|
||||
type InputFrameDecoded struct {
|
||||
@ -63,8 +66,8 @@ type Bullet struct {
|
||||
// for defender
|
||||
HitStunFrames int32
|
||||
BlockStunFrames int32
|
||||
PushbackX int32
|
||||
PushbackY int32
|
||||
PushbackVelX int32
|
||||
PushbackVelY int32
|
||||
Damage int32
|
||||
|
||||
SelfLockVelX int32
|
||||
|
@ -42,7 +42,7 @@ func NewBarrierJs(boundary *Polygon2D) *js.Object {
|
||||
})
|
||||
}
|
||||
|
||||
func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY, framesToRecover, framesInChState, speed, battleState, characterState, joinIndex, hp, maxHp int32, inAir bool, colliderRadius float64) *js.Object {
|
||||
func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY, framesToRecover, framesInChState, speed, battleState, characterState, joinIndex, hp, maxHp, colliderRadius int32, inAir bool) *js.Object {
|
||||
return js.MakeWrapper(&PlayerDownsync{
|
||||
Id: id,
|
||||
VirtualGridX: virtualGridX,
|
||||
@ -64,7 +64,7 @@ func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY,
|
||||
})
|
||||
}
|
||||
|
||||
func NewMeleeBulletJs(originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackX, pushbackY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY int32, blowUp bool) *js.Object {
|
||||
func NewMeleeBulletJs(originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY int32, blowUp bool) *js.Object {
|
||||
return js.MakeWrapper(&MeleeBullet{
|
||||
Bullet: Bullet{
|
||||
OriginatedRenderFrameId: originatedRenderFrameId,
|
||||
@ -77,8 +77,8 @@ func NewMeleeBulletJs(originatedRenderFrameId, offenderJoinIndex, startupFrames,
|
||||
|
||||
HitStunFrames: hitStunFrames,
|
||||
BlockStunFrames: blockStunFrames,
|
||||
PushbackX: pushbackX,
|
||||
PushbackY: pushbackY,
|
||||
PushbackVelX: pushbackVelX,
|
||||
PushbackVelY: pushbackVelY,
|
||||
Damage: damage,
|
||||
|
||||
SelfLockVelX: selfLockVelX,
|
||||
|
Loading…
Reference in New Issue
Block a user