mirror of
				https://github.com/genxium/DelayNoMore
				synced 2025-11-03 21:06:35 +00:00 
			
		
		
		
	Fixed fireball rollback mechanism.
This commit is contained in:
		@@ -55,62 +55,62 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for i, last := range rdf.MeleeBullets {
 | 
						for i, last := range rdf.MeleeBullets {
 | 
				
			||||||
		pbBullet := &pb.MeleeBullet{
 | 
							pbBullet := &pb.MeleeBullet{
 | 
				
			||||||
			BulletLocalId:           last.BulletLocalId,
 | 
								BulletLocalId:           last.Bullet.BulletLocalId,
 | 
				
			||||||
			OriginatedRenderFrameId: last.OriginatedRenderFrameId,
 | 
								OriginatedRenderFrameId: last.Bullet.OriginatedRenderFrameId,
 | 
				
			||||||
			OffenderJoinIndex:       last.OffenderJoinIndex,
 | 
								OffenderJoinIndex:       last.Bullet.OffenderJoinIndex,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			StartupFrames:      last.StartupFrames,
 | 
								StartupFrames:      last.Bullet.StartupFrames,
 | 
				
			||||||
			CancellableStFrame: last.CancellableStFrame,
 | 
								CancellableStFrame: last.Bullet.CancellableStFrame,
 | 
				
			||||||
			CancellableEdFrame: last.CancellableEdFrame,
 | 
								CancellableEdFrame: last.Bullet.CancellableEdFrame,
 | 
				
			||||||
			ActiveFrames:       last.ActiveFrames,
 | 
								ActiveFrames:       last.Bullet.ActiveFrames,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			HitStunFrames:   last.HitStunFrames,
 | 
								HitStunFrames:   last.Bullet.HitStunFrames,
 | 
				
			||||||
			BlockStunFrames: last.BlockStunFrames,
 | 
								BlockStunFrames: last.Bullet.BlockStunFrames,
 | 
				
			||||||
			PushbackVelX:    last.PushbackVelX,
 | 
								PushbackVelX:    last.Bullet.PushbackVelX,
 | 
				
			||||||
			PushbackVelY:    last.PushbackVelY,
 | 
								PushbackVelY:    last.Bullet.PushbackVelY,
 | 
				
			||||||
			Damage:          last.Damage,
 | 
								Damage:          last.Bullet.Damage,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			SelfLockVelX: last.SelfLockVelX,
 | 
								SelfLockVelX: last.Bullet.SelfLockVelX,
 | 
				
			||||||
			SelfLockVelY: last.SelfLockVelY,
 | 
								SelfLockVelY: last.Bullet.SelfLockVelY,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			HitboxOffsetX: last.HitboxOffsetX,
 | 
								HitboxOffsetX: last.Bullet.HitboxOffsetX,
 | 
				
			||||||
			HitboxOffsetY: last.HitboxOffsetY,
 | 
								HitboxOffsetY: last.Bullet.HitboxOffsetY,
 | 
				
			||||||
			HitboxSizeX:   last.HitboxSizeX,
 | 
								HitboxSizeX:   last.Bullet.HitboxSizeX,
 | 
				
			||||||
			HitboxSizeY:   last.HitboxSizeY,
 | 
								HitboxSizeY:   last.Bullet.HitboxSizeY,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			BlowUp: last.BlowUp,
 | 
								BlowUp: last.Bullet.BlowUp,
 | 
				
			||||||
			TeamId: last.TeamId,
 | 
								TeamId: last.Bullet.TeamId,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ret.MeleeBullets[i] = pbBullet
 | 
							ret.MeleeBullets[i] = pbBullet
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i, last := range rdf.FireballBullets {
 | 
						for i, last := range rdf.FireballBullets {
 | 
				
			||||||
		pbBullet := &pb.FireballBullet{
 | 
							pbBullet := &pb.FireballBullet{
 | 
				
			||||||
			BulletLocalId:           last.BulletLocalId,
 | 
								BulletLocalId:           last.Bullet.BulletLocalId,
 | 
				
			||||||
			OriginatedRenderFrameId: last.OriginatedRenderFrameId,
 | 
								OriginatedRenderFrameId: last.Bullet.OriginatedRenderFrameId,
 | 
				
			||||||
			OffenderJoinIndex:       last.OffenderJoinIndex,
 | 
								OffenderJoinIndex:       last.Bullet.OffenderJoinIndex,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			StartupFrames:      last.StartupFrames,
 | 
								StartupFrames:      last.Bullet.StartupFrames,
 | 
				
			||||||
			CancellableStFrame: last.CancellableStFrame,
 | 
								CancellableStFrame: last.Bullet.CancellableStFrame,
 | 
				
			||||||
			CancellableEdFrame: last.CancellableEdFrame,
 | 
								CancellableEdFrame: last.Bullet.CancellableEdFrame,
 | 
				
			||||||
			ActiveFrames:       last.ActiveFrames,
 | 
								ActiveFrames:       last.Bullet.ActiveFrames,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			HitStunFrames:   last.HitStunFrames,
 | 
								HitStunFrames:   last.Bullet.HitStunFrames,
 | 
				
			||||||
			BlockStunFrames: last.BlockStunFrames,
 | 
								BlockStunFrames: last.Bullet.BlockStunFrames,
 | 
				
			||||||
			PushbackVelX:    last.PushbackVelX,
 | 
								PushbackVelX:    last.Bullet.PushbackVelX,
 | 
				
			||||||
			PushbackVelY:    last.PushbackVelY,
 | 
								PushbackVelY:    last.Bullet.PushbackVelY,
 | 
				
			||||||
			Damage:          last.Damage,
 | 
								Damage:          last.Bullet.Damage,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			SelfLockVelX: last.SelfLockVelX,
 | 
								SelfLockVelX: last.Bullet.SelfLockVelX,
 | 
				
			||||||
			SelfLockVelY: last.SelfLockVelY,
 | 
								SelfLockVelY: last.Bullet.SelfLockVelY,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			HitboxOffsetX: last.HitboxOffsetX,
 | 
								HitboxOffsetX: last.Bullet.HitboxOffsetX,
 | 
				
			||||||
			HitboxOffsetY: last.HitboxOffsetY,
 | 
								HitboxOffsetY: last.Bullet.HitboxOffsetY,
 | 
				
			||||||
			HitboxSizeX:   last.HitboxSizeX,
 | 
								HitboxSizeX:   last.Bullet.HitboxSizeX,
 | 
				
			||||||
			HitboxSizeY:   last.HitboxSizeY,
 | 
								HitboxSizeY:   last.Bullet.HitboxSizeY,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			BlowUp: last.BlowUp,
 | 
								BlowUp: last.Bullet.BlowUp,
 | 
				
			||||||
			TeamId: last.TeamId,
 | 
								TeamId: last.Bullet.TeamId,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			VirtualGridX: last.VirtualGridX,
 | 
								VirtualGridX: last.VirtualGridX,
 | 
				
			||||||
			VirtualGridY: last.VirtualGridY,
 | 
								VirtualGridY: last.VirtualGridY,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -335,7 +335,20 @@ func (pR *Room) playerDownsyncStr(player *battle.PlayerDownsync) string {
 | 
				
			|||||||
	if player.InAir {
 | 
						if player.InAir {
 | 
				
			||||||
		inAirInt = 1
 | 
							inAirInt = 1
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	s := fmt.Sprintf("{%d,%d,%d,%d,%d,%d,%d}", player.JoinIndex, player.VirtualGridX, player.VirtualGridY, player.VelX, player.VelY, player.FramesToRecover, inAirInt)
 | 
						onWallInt := 0
 | 
				
			||||||
 | 
						if player.OnWall {
 | 
				
			||||||
 | 
							onWallInt = 1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s := fmt.Sprintf("{%d,%d,%d,%d,%d,%d,%d,%d}", player.JoinIndex, player.VirtualGridX, player.VirtualGridY, player.VelX, player.VelY, player.FramesToRecover, inAirInt, onWallInt)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return s
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (pR *Room) fireballDownsyncStr(fireball *battle.FireballBullet) string {
 | 
				
			||||||
 | 
						if nil == fireball {
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s := fmt.Sprintf("{%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d}", fireball.Bullet.BulletLocalId, fireball.Bullet.OriginatedRenderFrameId, fireball.Bullet.OffenderJoinIndex, fireball.VirtualGridX, fireball.VirtualGridY, fireball.VelX, fireball.VelY, fireball.DirX, fireball.DirY, fireball.Bullet.HitboxSizeX, fireball.Bullet.HitboxSizeY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return s
 | 
						return s
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -365,7 +378,11 @@ func (pR *Room) rdfIdToActuallyUsedInputString() string {
 | 
				
			|||||||
		for _, player := range rdf.PlayersArr {
 | 
							for _, player := range rdf.PlayersArr {
 | 
				
			||||||
			playersStrBldr = append(playersStrBldr, pR.playerDownsyncStr(player))
 | 
								playersStrBldr = append(playersStrBldr, pR.playerDownsyncStr(player))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		s = append(s, fmt.Sprintf("rdfId:%d\nplayers:[%v]\nactuallyUsedinputList:{%v}", rdfId, strings.Join(playersStrBldr, ","), pR.inputFrameDownsyncStr(pR.rdfIdToActuallyUsedInput[rdfId])))
 | 
							fireballsStrBldr := make([]string, 0, len(rdf.FireballBullets))
 | 
				
			||||||
 | 
							for _, fireball := range rdf.FireballBullets {
 | 
				
			||||||
 | 
								fireballsStrBldr = append(fireballsStrBldr, pR.fireballDownsyncStr(fireball))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							s = append(s, fmt.Sprintf("rdfId:%d\nplayers:[%v]\nfireballs:[%v]\nactuallyUsedinputList:{%v}", rdfId, strings.Join(playersStrBldr, ","), strings.Join(fireballsStrBldr, ","), pR.inputFrameDownsyncStr(pR.rdfIdToActuallyUsedInput[rdfId])))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return strings.Join(s, "\n")
 | 
						return strings.Join(s, "\n")
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -62,7 +62,7 @@
 | 
				
			|||||||
          {
 | 
					          {
 | 
				
			||||||
            "frame": 0.13333333333333333,
 | 
					            "frame": 0.13333333333333333,
 | 
				
			||||||
            "value": {
 | 
					            "value": {
 | 
				
			||||||
              "__uuid__": "2ad9becb-20e0-4bbb-b83b-de21e085e706"
 | 
					              "__uuid__": "dbe67025-9878-4e13-8f3d-81e04734810a"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,14 +5,14 @@
 | 
				
			|||||||
 <tileset firstgid="129" source="tiles2.tsx"/>
 | 
					 <tileset firstgid="129" source="tiles2.tsx"/>
 | 
				
			||||||
 <layer id="6" name="Ground" width="128" height="64">
 | 
					 <layer id="6" name="Ground" width="128" height="64">
 | 
				
			||||||
  <data encoding="base64" compression="zlib">
 | 
					  <data encoding="base64" compression="zlib">
 | 
				
			||||||
   eJzt2z1uAjEURWELlIYuiKRHyk4iGjo2wP6XkRDGUmThnxne+FncU3wNEDJ+x3aqbEMIWwAAAAAAAAAAAADo4IQ/3h08+3s/gzflGSivnRlor50ZaK+dGdTX/mb0e6y+h/7+/Q+NHn1P6z7YG32G/svWXur1TP/SvqL/OP1LnSz6t7Qt9a29T//x+7fcASW9ZvDKWvpbmbPHRprBKxt97e8ZSjPo3f/L4TnSOyDXfY19QP+xtLa32gcjzsCjf+u5Pxp9ZhT0v9tN6K/jtvbvRLwH0tejY6Pcz48mzsC7hVf/zSSe/+uvc8bGQO5veO39pWrPo37+0/438Q74/5pV/9HQ/+6c9H7EevafK5h799A/b5eZmdX9W+u1ZD/NaU//ED4mpZk9c/5Le6DX+S/tT/rn+1so3QM9+tfuJ/X+8O/g2f8ijv7a6K+N/tror43+2uivjf7a6K+N/tror43+2uivjf7a6K+N/tror43+2uivjf7a6K+N/trory3+D5R3C/rTn/70790f6/X/AbS6syo=
 | 
					   eJzt2ztuAjEURmELlIYuiKRHyk4iGjo2wP6XkRDGUmThxwx3fC3+U3wNw8v3eEyabEMIWwAAAAAAAAAAAADo4IQ/3h08+3t/B2/KM1BeOzPQXjsz0F47M6iv/c3oc6zeh/7+/Q+NHr1P6z7YGz2H/svWXur1TP/SvqL/OP1LnSz6t7Qt9a1dp//4/VvOgJJeM3hlLf2tzNljI83glY2+9vcMpRko9E/PgFz3NfbBKDNQ7r+kvdU+GHEGHv2/Gl9zNHrOKOh/t5vQX8dt7d+JeC19PDo2yr1+NHEG3i28+m8m8f6//jpnbAzkfsNr15eqfR/1+z/tfxP/Fvj/mFX/0dD/7pz0fsR69p8rmHv20D9vl5mZ1flb67VkP81pT/8QPialmT1z/5f2QK/7v7Q/6Z/vb6F0DvToXzuf1PvDv4Nn/4s4+mujvzb6a6O/Nvpro782+mujvzb6a6O/Nvpro782+mujvzb6a6O/Nvpro782+mujvzb6a6O/tvg/UN4t6E9/+tO/d3+s1/8HUhSy6A==
 | 
				
			||||||
  </data>
 | 
					  </data>
 | 
				
			||||||
 </layer>
 | 
					 </layer>
 | 
				
			||||||
 <objectgroup id="1" name="PlayerStartingPos">
 | 
					 <objectgroup id="1" name="PlayerStartingPos">
 | 
				
			||||||
  <object id="135" x="1630" y="518">
 | 
					  <object id="135" x="1140" y="488">
 | 
				
			||||||
   <point/>
 | 
					   <point/>
 | 
				
			||||||
  </object>
 | 
					  </object>
 | 
				
			||||||
  <object id="137" x="888.003" y="535">
 | 
					  <object id="137" x="1527" y="488">
 | 
				
			||||||
   <point/>
 | 
					   <point/>
 | 
				
			||||||
  </object>
 | 
					  </object>
 | 
				
			||||||
 </objectgroup>
 | 
					 </objectgroup>
 | 
				
			||||||
@@ -179,11 +179,6 @@
 | 
				
			|||||||
    <property name="boundary_type" value="barrier"/>
 | 
					    <property name="boundary_type" value="barrier"/>
 | 
				
			||||||
   </properties>
 | 
					   </properties>
 | 
				
			||||||
  </object>
 | 
					  </object>
 | 
				
			||||||
  <object id="126" x="720" y="480" width="16" height="16">
 | 
					 | 
				
			||||||
   <properties>
 | 
					 | 
				
			||||||
    <property name="boundary_type" value="barrier"/>
 | 
					 | 
				
			||||||
   </properties>
 | 
					 | 
				
			||||||
  </object>
 | 
					 | 
				
			||||||
  <object id="127" x="1088" y="320" width="16" height="16">
 | 
					  <object id="127" x="1088" y="320" width="16" height="16">
 | 
				
			||||||
   <properties>
 | 
					   <properties>
 | 
				
			||||||
    <property name="boundary_type" value="barrier"/>
 | 
					    <property name="boundary_type" value="barrier"/>
 | 
				
			||||||
@@ -209,10 +204,5 @@
 | 
				
			|||||||
    <property name="boundary_type" value="barrier"/>
 | 
					    <property name="boundary_type" value="barrier"/>
 | 
				
			||||||
   </properties>
 | 
					   </properties>
 | 
				
			||||||
  </object>
 | 
					  </object>
 | 
				
			||||||
  <object id="134" x="720" y="416" width="16" height="16">
 | 
					 | 
				
			||||||
   <properties>
 | 
					 | 
				
			||||||
    <property name="boundary_type" value="barrier"/>
 | 
					 | 
				
			||||||
   </properties>
 | 
					 | 
				
			||||||
  </object>
 | 
					 | 
				
			||||||
 </objectgroup>
 | 
					 </objectgroup>
 | 
				
			||||||
</map>
 | 
					</map>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,11 +24,11 @@
 | 
				
			|||||||
    "_active": true,
 | 
					    "_active": true,
 | 
				
			||||||
    "_components": [
 | 
					    "_components": [
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        "__id__": 6
 | 
					        "__id__": 7
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "_prefab": {
 | 
					    "_prefab": {
 | 
				
			||||||
      "__id__": 7
 | 
					      "__id__": 8
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "_opacity": 255,
 | 
					    "_opacity": 255,
 | 
				
			||||||
    "_color": {
 | 
					    "_color": {
 | 
				
			||||||
@@ -79,23 +79,20 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    "__type__": "cc.Node",
 | 
					    "__type__": "cc.Node",
 | 
				
			||||||
    "_name": "Fireball1",
 | 
					    "_name": "animNode",
 | 
				
			||||||
    "_objFlags": 0,
 | 
					    "_objFlags": 0,
 | 
				
			||||||
    "_parent": {
 | 
					    "_parent": {
 | 
				
			||||||
      "__id__": 1
 | 
					      "__id__": 1
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "_children": [],
 | 
					    "_children": [
 | 
				
			||||||
    "_active": false,
 | 
					 | 
				
			||||||
    "_components": [
 | 
					 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        "__id__": 3
 | 
					        "__id__": 3
 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        "__id__": 4
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
					    "_active": true,
 | 
				
			||||||
 | 
					    "_components": [],
 | 
				
			||||||
    "_prefab": {
 | 
					    "_prefab": {
 | 
				
			||||||
      "__id__": 5
 | 
					      "__id__": 6
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "_opacity": 255,
 | 
					    "_opacity": 255,
 | 
				
			||||||
    "_color": {
 | 
					    "_color": {
 | 
				
			||||||
@@ -145,20 +142,67 @@
 | 
				
			|||||||
    "_id": ""
 | 
					    "_id": ""
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    "__type__": "cc.Animation",
 | 
					    "__type__": "cc.Node",
 | 
				
			||||||
    "_name": "",
 | 
					    "_name": "Fireball1",
 | 
				
			||||||
    "_objFlags": 0,
 | 
					    "_objFlags": 0,
 | 
				
			||||||
    "node": {
 | 
					    "_parent": {
 | 
				
			||||||
      "__id__": 2
 | 
					      "__id__": 2
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "_enabled": true,
 | 
					    "_children": [],
 | 
				
			||||||
    "_defaultClip": null,
 | 
					    "_active": true,
 | 
				
			||||||
    "_clips": [
 | 
					    "_components": [
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        "__uuid__": "ba12416b-eec3-4260-8402-7fc25b125624"
 | 
					        "__id__": 4
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "playOnLoad": false,
 | 
					    "_prefab": {
 | 
				
			||||||
 | 
					      "__id__": 5
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "_opacity": 255,
 | 
				
			||||||
 | 
					    "_color": {
 | 
				
			||||||
 | 
					      "__type__": "cc.Color",
 | 
				
			||||||
 | 
					      "r": 255,
 | 
				
			||||||
 | 
					      "g": 255,
 | 
				
			||||||
 | 
					      "b": 255,
 | 
				
			||||||
 | 
					      "a": 255
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "_contentSize": {
 | 
				
			||||||
 | 
					      "__type__": "cc.Size",
 | 
				
			||||||
 | 
					      "width": 117,
 | 
				
			||||||
 | 
					      "height": 55
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "_anchorPoint": {
 | 
				
			||||||
 | 
					      "__type__": "cc.Vec2",
 | 
				
			||||||
 | 
					      "x": 0.5,
 | 
				
			||||||
 | 
					      "y": 0.5
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "_trs": {
 | 
				
			||||||
 | 
					      "__type__": "TypedArray",
 | 
				
			||||||
 | 
					      "ctor": "Float64Array",
 | 
				
			||||||
 | 
					      "array": [
 | 
				
			||||||
 | 
					        -32,
 | 
				
			||||||
 | 
					        0,
 | 
				
			||||||
 | 
					        0,
 | 
				
			||||||
 | 
					        0,
 | 
				
			||||||
 | 
					        0,
 | 
				
			||||||
 | 
					        0,
 | 
				
			||||||
 | 
					        1,
 | 
				
			||||||
 | 
					        1,
 | 
				
			||||||
 | 
					        1,
 | 
				
			||||||
 | 
					        1
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "_eulerAngles": {
 | 
				
			||||||
 | 
					      "__type__": "cc.Vec3",
 | 
				
			||||||
 | 
					      "x": 0,
 | 
				
			||||||
 | 
					      "y": 0,
 | 
				
			||||||
 | 
					      "z": 0
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "_skewX": 0,
 | 
				
			||||||
 | 
					    "_skewY": 0,
 | 
				
			||||||
 | 
					    "_is3DNode": false,
 | 
				
			||||||
 | 
					    "_groupIndex": 0,
 | 
				
			||||||
 | 
					    "groupIndex": 0,
 | 
				
			||||||
    "_id": ""
 | 
					    "_id": ""
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
@@ -166,13 +210,19 @@
 | 
				
			|||||||
    "_name": "",
 | 
					    "_name": "",
 | 
				
			||||||
    "_objFlags": 0,
 | 
					    "_objFlags": 0,
 | 
				
			||||||
    "node": {
 | 
					    "node": {
 | 
				
			||||||
      "__id__": 2
 | 
					      "__id__": 3
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "_enabled": true,
 | 
					    "_enabled": true,
 | 
				
			||||||
    "_materials": [],
 | 
					    "_materials": [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    "_srcBlendFactor": 770,
 | 
					    "_srcBlendFactor": 770,
 | 
				
			||||||
    "_dstBlendFactor": 771,
 | 
					    "_dstBlendFactor": 771,
 | 
				
			||||||
    "_spriteFrame": null,
 | 
					    "_spriteFrame": {
 | 
				
			||||||
 | 
					      "__uuid__": "e92702d5-d5fd-49e6-ab6b-2296b43fa6d6"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "_type": 0,
 | 
					    "_type": 0,
 | 
				
			||||||
    "_sizeMode": 1,
 | 
					    "_sizeMode": 1,
 | 
				
			||||||
    "_fillType": 0,
 | 
					    "_fillType": 0,
 | 
				
			||||||
@@ -197,7 +247,18 @@
 | 
				
			|||||||
    "asset": {
 | 
					    "asset": {
 | 
				
			||||||
      "__uuid__": "d92d4831-cd65-4eb5-90bd-b77021aec35b"
 | 
					      "__uuid__": "d92d4831-cd65-4eb5-90bd-b77021aec35b"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "fileId": "9ds3kDxvVFFqyr760jrV4a",
 | 
					    "fileId": "5f1s6pDt5F3rknJTu0gQW7",
 | 
				
			||||||
 | 
					    "sync": false
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "__type__": "cc.PrefabInfo",
 | 
				
			||||||
 | 
					    "root": {
 | 
				
			||||||
 | 
					      "__id__": 1
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "asset": {
 | 
				
			||||||
 | 
					      "__uuid__": "d92d4831-cd65-4eb5-90bd-b77021aec35b"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "fileId": "3824oBeVVL1KOAQ6Zd9CC5",
 | 
				
			||||||
    "sync": false
 | 
					    "sync": false
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
@@ -208,6 +269,9 @@
 | 
				
			|||||||
      "__id__": 1
 | 
					      "__id__": 1
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "_enabled": true,
 | 
					    "_enabled": true,
 | 
				
			||||||
 | 
					    "animNode": {
 | 
				
			||||||
 | 
					      "__id__": 2
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "_id": ""
 | 
					    "_id": ""
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -440,7 +440,7 @@
 | 
				
			|||||||
      "array": [
 | 
					      "array": [
 | 
				
			||||||
        0,
 | 
					        0,
 | 
				
			||||||
        0,
 | 
					        0,
 | 
				
			||||||
        216.50635094610968,
 | 
					        215.94663282292512,
 | 
				
			||||||
        0,
 | 
					        0,
 | 
				
			||||||
        0,
 | 
					        0,
 | 
				
			||||||
        0,
 | 
					        0,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -191,8 +191,8 @@
 | 
				
			|||||||
        0,
 | 
					        0,
 | 
				
			||||||
        0,
 | 
					        0,
 | 
				
			||||||
        1,
 | 
					        1,
 | 
				
			||||||
        1.2,
 | 
					        0.8,
 | 
				
			||||||
        1.2,
 | 
					        0.8,
 | 
				
			||||||
        1
 | 
					        1
 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -464,7 +464,7 @@
 | 
				
			|||||||
      "array": [
 | 
					      "array": [
 | 
				
			||||||
        0,
 | 
					        0,
 | 
				
			||||||
        0,
 | 
					        0,
 | 
				
			||||||
        209.57814771583418,
 | 
					        215.64032554232523,
 | 
				
			||||||
        0,
 | 
					        0,
 | 
				
			||||||
        0,
 | 
					        0,
 | 
				
			||||||
        0,
 | 
					        0,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,9 +29,6 @@ cc.Class({
 | 
				
			|||||||
    if (!selfPlayerRichInfo) return;
 | 
					    if (!selfPlayerRichInfo) return;
 | 
				
			||||||
    const selfPlayerNode = selfPlayerRichInfo.node;
 | 
					    const selfPlayerNode = selfPlayerRichInfo.node;
 | 
				
			||||||
    if (!selfPlayerNode) return;
 | 
					    if (!selfPlayerNode) return;
 | 
				
			||||||
      const pDiff = selfPlayerNode.position.sub(self.mainCamera.node.position); 
 | 
					    self.mapNode.setPosition(cc.v2().sub(selfPlayerNode.position));
 | 
				
			||||||
      pDiff.normalizeSelf();
 | 
					 | 
				
			||||||
      const newCamPos = self.mainCamera.node.position.add(pDiff.mul(dt*self.speed));
 | 
					 | 
				
			||||||
      self.mainCamera.node.setPosition(newCamPos);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,13 @@
 | 
				
			|||||||
cc.Class({
 | 
					cc.Class({
 | 
				
			||||||
  extends: cc.Component,
 | 
					  extends: cc.Component,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  properties: {
 | 
				
			||||||
 | 
					    animNode: {
 | 
				
			||||||
 | 
					      type: cc.Node,
 | 
				
			||||||
 | 
					      default: null
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ctor() {
 | 
					  ctor() {
 | 
				
			||||||
    this.lastUsed = -1;
 | 
					    this.lastUsed = -1;
 | 
				
			||||||
    this.bulletLocalId = -1;
 | 
					    this.bulletLocalId = -1;
 | 
				
			||||||
@@ -9,28 +16,30 @@ cc.Class({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  setSpecies(speciesName, fireballBullet, rdf) {
 | 
					  setSpecies(speciesName, fireballBullet, rdf) {
 | 
				
			||||||
    if (speciesName == this.speciesName) return;
 | 
					    if (speciesName == this.speciesName) return;
 | 
				
			||||||
    this.speciesName = speciesName;
 | 
					    if (null != this.speciesName) {
 | 
				
			||||||
    this.effAnimNode = this.node.getChildByName(this.speciesName);
 | 
					      for (let k in this.animNode.children) {
 | 
				
			||||||
    this.animComp = this.effAnimNode.getComponent(cc.Animation);
 | 
					 | 
				
			||||||
    this.effAnimNode.active = true;
 | 
					 | 
				
			||||||
    for (let k in this.children) {
 | 
					 | 
				
			||||||
        const child = this.children[k];
 | 
					        const child = this.children[k];
 | 
				
			||||||
        if (!child.active) continue;
 | 
					        if (!child.active) continue;
 | 
				
			||||||
        if (child == effAnimNode || child.name == speciesName) continue;
 | 
					        if (child == effAnimNode || child.name == speciesName) continue;
 | 
				
			||||||
        child.active = false;
 | 
					        child.active = false;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    this.updateAnim(speciesName, fireballBullet, rdf);
 | 
					    }
 | 
				
			||||||
 | 
					    this.speciesName = speciesName;
 | 
				
			||||||
 | 
					    this.effAnimNode = this.animNode.getChildByName(this.speciesName);
 | 
				
			||||||
 | 
					    this.effAnimNode.active = true;
 | 
				
			||||||
 | 
					    //this.updateAnim(speciesName, fireballBullet, rdf);
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onLoad() {},
 | 
					  onLoad() {},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  updateAnim(speciesName, fireballBullet, rdf) {
 | 
					  updateAnim(speciesName, fireballBullet, rdf) {
 | 
				
			||||||
 | 
					    this.animComp = this.effAnimNode.getComponent(cc.Animation);
 | 
				
			||||||
    // Update directions
 | 
					    // Update directions
 | 
				
			||||||
    if (this.animComp && this.animComp.node) {
 | 
					    if (this.animComp && this.animComp.node) {
 | 
				
			||||||
      if (0 > fireballBullet.DirX) {
 | 
					      if (0 > fireballBullet.DirX) {
 | 
				
			||||||
        this.effAnimNode.scaleX = (-1.0);
 | 
					        this.animNode.scaleX = (-1.0);
 | 
				
			||||||
      } else if (0 < fireballBullet.DirX) {
 | 
					      } else if (0 < fireballBullet.DirX) {
 | 
				
			||||||
        this.effAnimNode.scaleX = (1.0);
 | 
					        this.animNode.scaleX = (1.0);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -413,7 +413,7 @@ cc.Class({
 | 
				
			|||||||
    window.mapIns = self;
 | 
					    window.mapIns = self;
 | 
				
			||||||
    window.forceBigEndianFloatingNumDecoding = self.forceBigEndianFloatingNumDecoding;
 | 
					    window.forceBigEndianFloatingNumDecoding = self.forceBigEndianFloatingNumDecoding;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    self.showCriticalCoordinateLabels = true;
 | 
					    self.showCriticalCoordinateLabels = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    console.warn("+++++++ Map onLoad()");
 | 
					    console.warn("+++++++ Map onLoad()");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1095,23 +1095,6 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  _renderFireballBullet(fireballBullet, rdf) {
 | 
					  _renderFireballBullet(fireballBullet, rdf) {
 | 
				
			||||||
    const self = this;
 | 
					    const self = this;
 | 
				
			||||||
    let pqNode = self.cachedFireballs.popAny(fireballBullet.Bullet.BulletLocalId);
 | 
					 | 
				
			||||||
    const speciesName = `Fireball${fireballBullet.SpeciesId}`;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (null == pqNode) {
 | 
					 | 
				
			||||||
      pqNode = self.cachedFireballs.pop();
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      console.log(`Using a cached fireball node for rendering for bulletLocalId=${fireballBullet.Bullet.BulletLocalId}`);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    const cachedFireball = pqNode.value;
 | 
					 | 
				
			||||||
    cachedFireball.setSpecies(speciesName, fireballBullet, rdf);
 | 
					 | 
				
			||||||
    cachedFireball.lastUsed = self.renderFrameId;
 | 
					 | 
				
			||||||
    cachedFireball.bulletLocalId = fireballBullet.Bullet.BulletLocalId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const [wx, wy] = gopkgs.VirtualGridToWorldPos(fireballBullet.VirtualGridX, fireballBullet.VirtualGridY);
 | 
					 | 
				
			||||||
    cachedFireball.node.setPosition(cc.v2(wx, wy));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    self.cachedFireballs.push(cachedFireball.lastUsed, cachedFireball, cachedFireball.bulletLocalId);
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  applyRoomDownsyncFrameDynamics(rdf, prevRdf) {
 | 
					  applyRoomDownsyncFrameDynamics(rdf, prevRdf) {
 | 
				
			||||||
@@ -1137,8 +1120,28 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
 | 
				
			|||||||
    const fireballBullets = rdf.FireballBullets;
 | 
					    const fireballBullets = rdf.FireballBullets;
 | 
				
			||||||
    for (let k in fireballBullets) {
 | 
					    for (let k in fireballBullets) {
 | 
				
			||||||
      const fireballBullet = fireballBullets[k];
 | 
					      const fireballBullet = fireballBullets[k];
 | 
				
			||||||
      if ((fireballBullet.Bullet.OriginatedRenderFrameId + fireballBullet.Bullet.StartupFrames <= rdf.Id) && (fireballBullet.Bullet.OriginatedRenderFrameId + fireballBullet.Bullet.StartupFrames + fireballBullet.Bullet.ActiveFrames > rdf.Id)) {
 | 
					      if (
 | 
				
			||||||
        self._renderFireballBullet(fireballBullet, rdf);
 | 
					        fireballBullet.Bullet.OriginatedRenderFrameId + fireballBullet.Bullet.StartupFrames <= rdf.Id
 | 
				
			||||||
 | 
					        &&
 | 
				
			||||||
 | 
					        fireballBullet.Bullet.OriginatedRenderFrameId + fireballBullet.Bullet.StartupFrames + fireballBullet.Bullet.ActiveFrames > rdf.Id
 | 
				
			||||||
 | 
					      ) {
 | 
				
			||||||
 | 
					        let pqNode = self.cachedFireballs.popAny(fireballBullet.Bullet.BulletLocalId);
 | 
				
			||||||
 | 
					        const speciesName = `Fireball${fireballBullet.SpeciesId}`;
 | 
				
			||||||
 | 
					        const [wx, wy] = gopkgs.VirtualGridToWorldPos(fireballBullet.VirtualGridX, fireballBullet.VirtualGridY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (null == pqNode) {
 | 
				
			||||||
 | 
					          pqNode = self.cachedFireballs.pop();
 | 
				
			||||||
 | 
					          console.log(`@rdf.Id=${rdf.Id}, origRdfId=${fireballBullet.Bullet.OriginatedRenderFrameId}, startupFrames=${fireballBullet.Bullet.StartupFrames}, activeFrames=${fireballBullet.Bullet.ActiveFrames}, using a new fireball node for rendering for bulletLocalId=${fireballBullet.Bullet.BulletLocalId} at wpos=(${wx},${wy})`);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          console.log(`@rdf.Id=${rdf.Id}, origRdfId=${fireballBullet.Bullet.OriginatedRenderFrameId}, startupFrames=${fireballBullet.Bullet.StartupFrames}, activeFrames=${fireballBullet.Bullet.ActiveFrames}, using a cached fireball node for rendering for bulletLocalId=${fireballBullet.Bullet.BulletLocalId} at wpos=(${wx},${wy})`);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        const cachedFireball = pqNode.value;
 | 
				
			||||||
 | 
					        cachedFireball.setSpecies(speciesName, fireballBullet, rdf);
 | 
				
			||||||
 | 
					        cachedFireball.lastUsed = self.renderFrameId;
 | 
				
			||||||
 | 
					        cachedFireball.bulletLocalId = fireballBullet.Bullet.BulletLocalId;
 | 
				
			||||||
 | 
					        cachedFireball.node.setPosition(cc.v2(wx, wy));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.cachedFireballs.push(cachedFireball.lastUsed, cachedFireball, fireballBullet.Bullet.BulletLocalId);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1263,7 +1266,12 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  playerDownsyncStr(playerDownsync) {
 | 
					  playerDownsyncStr(playerDownsync) {
 | 
				
			||||||
    if (null == playerDownsync) return "";
 | 
					    if (null == playerDownsync) return "";
 | 
				
			||||||
    return `{${playerDownsync.JoinIndex},${playerDownsync.VirtualGridX},${playerDownsync.VirtualGridY},${playerDownsync.VelX},${playerDownsync.VelY},${playerDownsync.FramesToRecover},${playerDownsync.InAir ? 1 : 0}}`;
 | 
					    return `{${playerDownsync.JoinIndex},${playerDownsync.VirtualGridX},${playerDownsync.VirtualGridY},${playerDownsync.VelX},${playerDownsync.VelY},${playerDownsync.FramesToRecover},${playerDownsync.InAir ? 1 : 0},${playerDownsync.OnWall ? 1 : 0}}`;
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fireballDownsyncStr(fireball) {
 | 
				
			||||||
 | 
					    if (null == fireball) return "";
 | 
				
			||||||
 | 
					    return `{${fireball.Bullet.BulletLocalId},${fireball.Bullet.OriginatedRenderFrameId},${fireball.Bullet.OffenderJoinIndex},${fireball.VirtualGridX},${fireball.VirtualGridY},${fireball.VelX},${fireball.VelY},${fireball.DirX},${fireball.DirY},${fireball.Bullet.HitboxSizeX},${fireball.Bullet.HitboxSizeY}}`;
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  inputFrameDownsyncStr(inputFrameDownsync) {
 | 
					  inputFrameDownsyncStr(inputFrameDownsync) {
 | 
				
			||||||
@@ -1292,8 +1300,13 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
 | 
				
			|||||||
      for (let k in rdf.PlayersArr) {
 | 
					      for (let k in rdf.PlayersArr) {
 | 
				
			||||||
        playersStrBldr.push(self.playerDownsyncStr(rdf.PlayersArr[k]));
 | 
					        playersStrBldr.push(self.playerDownsyncStr(rdf.PlayersArr[k]));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      const fireballsStrBldr = [];
 | 
				
			||||||
 | 
					      for (let k in rdf.FireballBullets) {
 | 
				
			||||||
 | 
					        fireballsStrBldr.push(self.fireballDownsyncStr(rdf.FireballBullets[k]));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      s.push(`rdfId:${i}
 | 
					      s.push(`rdfId:${i}
 | 
				
			||||||
players:[${playersStrBldr.join(',')}]
 | 
					players:[${playersStrBldr.join(',')}]
 | 
				
			||||||
 | 
					fireballs:[${fireballsStrBldr.join(',')}]
 | 
				
			||||||
actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`);
 | 
					actuallyUsedinputList:{${self.inputFrameDownsyncStr(actuallyUsedInputClone)}}`);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -94,7 +94,7 @@ cc.Class({
 | 
				
			|||||||
      const p2Vpos = gopkgs.WorldToVirtualGridPos(boundaryObjs.playerStartingPositions[1].x, boundaryObjs.playerStartingPositions[1].y);
 | 
					      const p2Vpos = gopkgs.WorldToVirtualGridPos(boundaryObjs.playerStartingPositions[1].x, boundaryObjs.playerStartingPositions[1].y);
 | 
				
			||||||
      const colliderRadiusV = gopkgs.WorldToVirtualGridPos(12.0, 0);
 | 
					      const colliderRadiusV = gopkgs.WorldToVirtualGridPos(12.0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const speciesIdList = [1, 4096];
 | 
					      const speciesIdList = [4096, 1];
 | 
				
			||||||
      const chConfigsOrderedByJoinIndex = gopkgs.GetCharacterConfigsOrderedByJoinIndex(speciesIdList);
 | 
					      const chConfigsOrderedByJoinIndex = gopkgs.GetCharacterConfigsOrderedByJoinIndex(speciesIdList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const startRdf = window.pb.protos.RoomDownsyncFrame.create({
 | 
					      const startRdf = window.pb.protos.RoomDownsyncFrame.create({
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@ package battle
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"math"
 | 
						"math"
 | 
				
			||||||
	"resolv"
 | 
						"resolv"
 | 
				
			||||||
 | 
						//"fmt"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -21,7 +22,7 @@ const (
 | 
				
			|||||||
	GRAVITY_X = int32(0)
 | 
						GRAVITY_X = int32(0)
 | 
				
			||||||
	GRAVITY_Y = -int32(float64(0.5) * WORLD_TO_VIRTUAL_GRID_RATIO) // makes all "playerCollider.Y" a multiple of 0.5 in all cases
 | 
						GRAVITY_Y = -int32(float64(0.5) * WORLD_TO_VIRTUAL_GRID_RATIO) // makes all "playerCollider.Y" a multiple of 0.5 in all cases
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	INPUT_DELAY_FRAMES = int32(8)  // in the count of render frames
 | 
						INPUT_DELAY_FRAMES = int32(4)  // in the count of render frames
 | 
				
			||||||
	INPUT_SCALE_FRAMES = uint32(2) // inputDelayedAndScaledFrameId = ((originalFrameId - InputDelayFrames) >> InputScaleFrames)
 | 
						INPUT_SCALE_FRAMES = uint32(2) // inputDelayedAndScaledFrameId = ((originalFrameId - InputDelayFrames) >> InputScaleFrames)
 | 
				
			||||||
	NST_DELAY_FRAMES   = int32(16) // network-single-trip delay in the count of render frames, proposed to be (InputDelayFrames >> 1) because we expect a round-trip delay to be exactly "InputDelayFrames"
 | 
						NST_DELAY_FRAMES   = int32(16) // network-single-trip delay in the count of render frames, proposed to be (InputDelayFrames >> 1) because we expect a round-trip delay to be exactly "InputDelayFrames"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -509,6 +510,7 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// [WARNING] For rollback compatibility, MeleeBullets are composed of only static BulletConfig data and move along with the offenders, therefore they can just be copies of the pointers in "RenderFrameBuffer", however, FireballBullets move on their own and must be copies of instances for each RenderFrame!
 | 
				
			||||||
	nextRenderFrameMeleeBullets := make([]*MeleeBullet, 0, len(currRenderFrame.MeleeBullets)) // Is there any better way to reduce malloc/free impact, e.g. smart prediction for fixed memory allocation?
 | 
						nextRenderFrameMeleeBullets := make([]*MeleeBullet, 0, len(currRenderFrame.MeleeBullets)) // Is there any better way to reduce malloc/free impact, e.g. smart prediction for fixed memory allocation?
 | 
				
			||||||
	nextRenderFrameFireballBullets := make([]*FireballBullet, 0, len(currRenderFrame.FireballBullets))
 | 
						nextRenderFrameFireballBullets := make([]*FireballBullet, 0, len(currRenderFrame.FireballBullets))
 | 
				
			||||||
	effPushbacks := make([]Vec2D, roomCapacity)
 | 
						effPushbacks := make([]Vec2D, roomCapacity)
 | 
				
			||||||
@@ -539,38 +541,39 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
 | 
				
			|||||||
			switch v := skillConfig.Hits[thatPlayerInNextFrame.ActiveSkillHit].(type) {
 | 
								switch v := skillConfig.Hits[thatPlayerInNextFrame.ActiveSkillHit].(type) {
 | 
				
			||||||
			case *MeleeBullet:
 | 
								case *MeleeBullet:
 | 
				
			||||||
				var newBullet MeleeBullet = *v // Copied primitive fields into an onstack variable
 | 
									var newBullet MeleeBullet = *v // Copied primitive fields into an onstack variable
 | 
				
			||||||
				newBullet.BulletLocalId = bulletLocalId
 | 
									newBullet.Bullet.BulletLocalId = bulletLocalId
 | 
				
			||||||
				bulletLocalId++
 | 
									bulletLocalId++
 | 
				
			||||||
				newBullet.OriginatedRenderFrameId = currRenderFrame.Id
 | 
									newBullet.Bullet.OriginatedRenderFrameId = currRenderFrame.Id
 | 
				
			||||||
				newBullet.OffenderJoinIndex = joinIndex
 | 
									newBullet.Bullet.OffenderJoinIndex = joinIndex
 | 
				
			||||||
				nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, &newBullet)
 | 
									nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, &newBullet)
 | 
				
			||||||
				if NO_LOCK_VEL != v.SelfLockVelX {
 | 
									if NO_LOCK_VEL != v.Bullet.SelfLockVelX {
 | 
				
			||||||
					hasLockVel = true
 | 
										hasLockVel = true
 | 
				
			||||||
					thatPlayerInNextFrame.VelX = xfac * v.SelfLockVelX
 | 
										thatPlayerInNextFrame.VelX = xfac * v.Bullet.SelfLockVelX
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if NO_LOCK_VEL != v.SelfLockVelY {
 | 
									if NO_LOCK_VEL != v.Bullet.SelfLockVelY {
 | 
				
			||||||
					hasLockVel = true
 | 
										hasLockVel = true
 | 
				
			||||||
					thatPlayerInNextFrame.VelY = v.SelfLockVelY
 | 
										thatPlayerInNextFrame.VelY = v.Bullet.SelfLockVelY
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			case *FireballBullet:
 | 
								case *FireballBullet:
 | 
				
			||||||
				var newBullet FireballBullet = *v // Copied primitive fields into an onstack variable
 | 
									var newBullet FireballBullet = *v // Copied primitive fields into an onstack variable
 | 
				
			||||||
				newBullet.BulletLocalId = bulletLocalId
 | 
									newBullet.Bullet.BulletLocalId = bulletLocalId
 | 
				
			||||||
				bulletLocalId++
 | 
									bulletLocalId++
 | 
				
			||||||
				newBullet.VirtualGridX, newBullet.VirtualGridY = currPlayerDownsync.VirtualGridX+xfac*newBullet.HitboxOffsetX, currPlayerDownsync.VirtualGridY+newBullet.HitboxOffsetY
 | 
									newBullet.Bullet.OriginatedRenderFrameId = currRenderFrame.Id
 | 
				
			||||||
				newBullet.OriginatedRenderFrameId = currRenderFrame.Id
 | 
									newBullet.Bullet.OffenderJoinIndex = joinIndex
 | 
				
			||||||
				newBullet.OffenderJoinIndex = joinIndex
 | 
									newBullet.VirtualGridX, newBullet.VirtualGridY = currPlayerDownsync.VirtualGridX+xfac*newBullet.Bullet.HitboxOffsetX, currPlayerDownsync.VirtualGridY+newBullet.Bullet.HitboxOffsetY
 | 
				
			||||||
				newBullet.DirX = xfac
 | 
									newBullet.DirX = xfac
 | 
				
			||||||
				newBullet.DirY = 0
 | 
									newBullet.DirY = 0
 | 
				
			||||||
				newBullet.VelX = newBullet.Speed * xfac
 | 
									newBullet.VelX = newBullet.Speed * xfac
 | 
				
			||||||
				newBullet.VelY = 0
 | 
									newBullet.VelY = 0
 | 
				
			||||||
				nextRenderFrameFireballBullets = append(nextRenderFrameFireballBullets, &newBullet)
 | 
									nextRenderFrameFireballBullets = append(nextRenderFrameFireballBullets, &newBullet)
 | 
				
			||||||
				if NO_LOCK_VEL != v.SelfLockVelX {
 | 
									//fmt.Printf("Created new fireball @currRenderFrame.Id=%d, %p, bulletLocalId=%d, virtualGridX=%d, virtualGridY=%d, offenderVpos=(%d,%d)\n", currRenderFrame.Id, &newBullet, bulletLocalId, newBullet.VirtualGridX, newBullet.VirtualGridY, currPlayerDownsync.VirtualGridX, currPlayerDownsync.VirtualGridY)
 | 
				
			||||||
 | 
									if NO_LOCK_VEL != v.Bullet.SelfLockVelX {
 | 
				
			||||||
					hasLockVel = true
 | 
										hasLockVel = true
 | 
				
			||||||
					thatPlayerInNextFrame.VelX = xfac * v.SelfLockVelX
 | 
										thatPlayerInNextFrame.VelX = xfac * v.Bullet.SelfLockVelX
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if NO_LOCK_VEL != v.SelfLockVelY {
 | 
									if NO_LOCK_VEL != v.Bullet.SelfLockVelY {
 | 
				
			||||||
					hasLockVel = true
 | 
										hasLockVel = true
 | 
				
			||||||
					thatPlayerInNextFrame.VelY = v.SelfLockVelY
 | 
										thatPlayerInNextFrame.VelY = v.Bullet.SelfLockVelY
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -666,31 +669,43 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
 | 
				
			|||||||
	// 3. Add bullet colliders into collision system
 | 
						// 3. Add bullet colliders into collision system
 | 
				
			||||||
	bulletColliders := make([]*resolv.Object, 0, len(currRenderFrame.MeleeBullets)) // Will all be removed at the end of this function due to the need for being rollback-compatible
 | 
						bulletColliders := make([]*resolv.Object, 0, len(currRenderFrame.MeleeBullets)) // Will all be removed at the end of this function due to the need for being rollback-compatible
 | 
				
			||||||
	for _, meleeBullet := range currRenderFrame.MeleeBullets {
 | 
						for _, meleeBullet := range currRenderFrame.MeleeBullets {
 | 
				
			||||||
		if (meleeBullet.OriginatedRenderFrameId+meleeBullet.StartupFrames <= currRenderFrame.Id) && (meleeBullet.OriginatedRenderFrameId+meleeBullet.StartupFrames+meleeBullet.ActiveFrames > currRenderFrame.Id) {
 | 
							if (meleeBullet.Bullet.OriginatedRenderFrameId+meleeBullet.Bullet.StartupFrames <= currRenderFrame.Id) && (meleeBullet.Bullet.OriginatedRenderFrameId+meleeBullet.Bullet.StartupFrames+meleeBullet.Bullet.ActiveFrames > currRenderFrame.Id) {
 | 
				
			||||||
			offender := currRenderFrame.PlayersArr[meleeBullet.OffenderJoinIndex-1]
 | 
								offender := currRenderFrame.PlayersArr[meleeBullet.Bullet.OffenderJoinIndex-1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			xfac := int32(1) // By now, straight Punch offset doesn't respect "y-axis"
 | 
								xfac := int32(1) // By now, straight Punch offset doesn't respect "y-axis"
 | 
				
			||||||
			if 0 > offender.DirX {
 | 
								if 0 > offender.DirX {
 | 
				
			||||||
				xfac = -xfac
 | 
									xfac = -xfac
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			bulletWx, bulletWy := VirtualGridToWorldPos(offender.VirtualGridX+xfac*meleeBullet.HitboxOffsetX, offender.VirtualGridY)
 | 
								bulletWx, bulletWy := VirtualGridToWorldPos(offender.VirtualGridX+xfac*meleeBullet.Bullet.HitboxOffsetX, offender.VirtualGridY)
 | 
				
			||||||
			hitboxSizeWx, hitboxSizeWy := VirtualGridToWorldPos(meleeBullet.HitboxSizeX, meleeBullet.HitboxSizeY)
 | 
								hitboxSizeWx, hitboxSizeWy := VirtualGridToWorldPos(meleeBullet.Bullet.HitboxSizeX, meleeBullet.Bullet.HitboxSizeY)
 | 
				
			||||||
			newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, hitboxSizeWx, hitboxSizeWy, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, collisionSpaceOffsetX, collisionSpaceOffsetY, meleeBullet, "MeleeBullet")
 | 
								newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, hitboxSizeWx, hitboxSizeWy, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, collisionSpaceOffsetX, collisionSpaceOffsetY, meleeBullet, "MeleeBullet")
 | 
				
			||||||
			collisionSys.Add(newBulletCollider)
 | 
								collisionSys.Add(newBulletCollider)
 | 
				
			||||||
			bulletColliders = append(bulletColliders, newBulletCollider)
 | 
								bulletColliders = append(bulletColliders, newBulletCollider)
 | 
				
			||||||
		} else if meleeBullet.OriginatedRenderFrameId+meleeBullet.StartupFrames+meleeBullet.ActiveFrames > currRenderFrame.Id {
 | 
							} else if meleeBullet.Bullet.OriginatedRenderFrameId+meleeBullet.Bullet.StartupFrames+meleeBullet.Bullet.ActiveFrames > currRenderFrame.Id {
 | 
				
			||||||
			nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, meleeBullet)
 | 
								nextRenderFrameMeleeBullets = append(nextRenderFrameMeleeBullets, meleeBullet)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, fireballBullet := range currRenderFrame.FireballBullets {
 | 
						for _, prevFireball := range currRenderFrame.FireballBullets {
 | 
				
			||||||
		if (fireballBullet.OriginatedRenderFrameId+fireballBullet.StartupFrames < currRenderFrame.Id) && (fireballBullet.OriginatedRenderFrameId+fireballBullet.StartupFrames+fireballBullet.ActiveFrames > currRenderFrame.Id) {
 | 
							fireballBullet := &FireballBullet{
 | 
				
			||||||
 | 
								VirtualGridX: prevFireball.VirtualGridX,
 | 
				
			||||||
 | 
								VirtualGridY: prevFireball.VirtualGridY,
 | 
				
			||||||
 | 
								DirX:         prevFireball.DirX,
 | 
				
			||||||
 | 
								DirY:         prevFireball.DirY,
 | 
				
			||||||
 | 
								VelX:         prevFireball.VelX,
 | 
				
			||||||
 | 
								VelY:         prevFireball.VelY,
 | 
				
			||||||
 | 
								Speed:        prevFireball.Speed,
 | 
				
			||||||
 | 
								SpeciesId:    prevFireball.SpeciesId,
 | 
				
			||||||
 | 
								Bullet:       prevFireball.Bullet,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (fireballBullet.Bullet.OriginatedRenderFrameId+fireballBullet.Bullet.StartupFrames < currRenderFrame.Id) && (fireballBullet.Bullet.OriginatedRenderFrameId+fireballBullet.Bullet.StartupFrames+fireballBullet.Bullet.ActiveFrames > currRenderFrame.Id) {
 | 
				
			||||||
			bulletWx, bulletWy := VirtualGridToWorldPos(fireballBullet.VirtualGridX, fireballBullet.VirtualGridY)
 | 
								bulletWx, bulletWy := VirtualGridToWorldPos(fireballBullet.VirtualGridX, fireballBullet.VirtualGridY)
 | 
				
			||||||
			hitboxSizeWx, hitboxSizeWy := VirtualGridToWorldPos(fireballBullet.HitboxSizeX, fireballBullet.HitboxSizeY)
 | 
								hitboxSizeWx, hitboxSizeWy := VirtualGridToWorldPos(fireballBullet.Bullet.HitboxSizeX, fireballBullet.Bullet.HitboxSizeY)
 | 
				
			||||||
			newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, hitboxSizeWx, hitboxSizeWy, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, collisionSpaceOffsetX, collisionSpaceOffsetY, fireballBullet, "FireballBullet")
 | 
								newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, hitboxSizeWx, hitboxSizeWy, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, SNAP_INTO_PLATFORM_OVERLAP, collisionSpaceOffsetX, collisionSpaceOffsetY, fireballBullet, "FireballBullet")
 | 
				
			||||||
			collisionSys.Add(newBulletCollider)
 | 
								collisionSys.Add(newBulletCollider)
 | 
				
			||||||
			bulletColliders = append(bulletColliders, newBulletCollider)
 | 
								bulletColliders = append(bulletColliders, newBulletCollider)
 | 
				
			||||||
		} else if fireballBullet.OriginatedRenderFrameId+fireballBullet.StartupFrames+fireballBullet.ActiveFrames > currRenderFrame.Id {
 | 
							} else if fireballBullet.Bullet.OriginatedRenderFrameId+fireballBullet.Bullet.StartupFrames+fireballBullet.Bullet.ActiveFrames > currRenderFrame.Id {
 | 
				
			||||||
 | 
								// fmt.Printf("Pushing static fireball to next frame @currRenderFrame.Id=%d, bulletLocalId=%d, virtualGridX=%d, virtualGridY=%d\n", currRenderFrame.Id, fireballBullet.BulletLocalId, fireballBullet.VirtualGridX, fireballBullet.VirtualGridY)
 | 
				
			||||||
			nextRenderFrameFireballBullets = append(nextRenderFrameFireballBullets, fireballBullet)
 | 
								nextRenderFrameFireballBullets = append(nextRenderFrameFireballBullets, fireballBullet)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -828,12 +843,12 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
 | 
				
			|||||||
			switch v := bulletCollider.Data.(type) {
 | 
								switch v := bulletCollider.Data.(type) {
 | 
				
			||||||
			case *MeleeBullet:
 | 
								case *MeleeBullet:
 | 
				
			||||||
				bulletShape := bulletCollider.Shape.(*resolv.ConvexPolygon)
 | 
									bulletShape := bulletCollider.Shape.(*resolv.ConvexPolygon)
 | 
				
			||||||
				offender := currRenderFrame.PlayersArr[v.OffenderJoinIndex-1]
 | 
									offender := currRenderFrame.PlayersArr[v.Bullet.OffenderJoinIndex-1]
 | 
				
			||||||
				for _, obj := range collision.Objects {
 | 
									for _, obj := range collision.Objects {
 | 
				
			||||||
					defenderShape := obj.Shape.(*resolv.ConvexPolygon)
 | 
										defenderShape := obj.Shape.(*resolv.ConvexPolygon)
 | 
				
			||||||
					switch t := obj.Data.(type) {
 | 
										switch t := obj.Data.(type) {
 | 
				
			||||||
					case *PlayerDownsync:
 | 
										case *PlayerDownsync:
 | 
				
			||||||
						if v.OffenderJoinIndex == t.JoinIndex {
 | 
											if v.Bullet.OffenderJoinIndex == t.JoinIndex {
 | 
				
			||||||
							continue
 | 
												continue
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						overlapped, _, _, _ := calcPushbacks(0, 0, bulletShape, defenderShape)
 | 
											overlapped, _, _, _ := calcPushbacks(0, 0, bulletShape, defenderShape)
 | 
				
			||||||
@@ -851,18 +866,18 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
 | 
				
			|||||||
						if 0 > offender.DirX {
 | 
											if 0 > offender.DirX {
 | 
				
			||||||
							xfac = -xfac
 | 
												xfac = -xfac
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						pushbackVelX, pushbackVelY := xfac*v.PushbackVelX, v.PushbackVelY
 | 
											pushbackVelX, pushbackVelY := xfac*v.Bullet.PushbackVelX, v.Bullet.PushbackVelY
 | 
				
			||||||
						atkedPlayerInNextFrame := nextRenderFramePlayers[t.JoinIndex-1]
 | 
											atkedPlayerInNextFrame := nextRenderFramePlayers[t.JoinIndex-1]
 | 
				
			||||||
						atkedPlayerInNextFrame.VelX = pushbackVelX
 | 
											atkedPlayerInNextFrame.VelX = pushbackVelX
 | 
				
			||||||
						atkedPlayerInNextFrame.VelY = pushbackVelY
 | 
											atkedPlayerInNextFrame.VelY = pushbackVelY
 | 
				
			||||||
						if v.BlowUp {
 | 
											if v.Bullet.BlowUp {
 | 
				
			||||||
							atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_BLOWN_UP1
 | 
												atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_BLOWN_UP1
 | 
				
			||||||
						} else {
 | 
											} else {
 | 
				
			||||||
							atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATKED1
 | 
												atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATKED1
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						oldFramesToRecover := nextRenderFramePlayers[t.JoinIndex-1].FramesToRecover
 | 
											oldFramesToRecover := nextRenderFramePlayers[t.JoinIndex-1].FramesToRecover
 | 
				
			||||||
						if v.HitStunFrames > oldFramesToRecover {
 | 
											if v.Bullet.HitStunFrames > oldFramesToRecover {
 | 
				
			||||||
							atkedPlayerInNextFrame.FramesToRecover = v.HitStunFrames
 | 
												atkedPlayerInNextFrame.FramesToRecover = v.Bullet.HitStunFrames
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					default:
 | 
										default:
 | 
				
			||||||
						addToNextRenderFrame = false
 | 
											addToNextRenderFrame = false
 | 
				
			||||||
@@ -870,12 +885,12 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			case *FireballBullet:
 | 
								case *FireballBullet:
 | 
				
			||||||
				bulletShape := bulletCollider.Shape.(*resolv.ConvexPolygon)
 | 
									bulletShape := bulletCollider.Shape.(*resolv.ConvexPolygon)
 | 
				
			||||||
				offender := currRenderFrame.PlayersArr[v.OffenderJoinIndex-1]
 | 
									offender := currRenderFrame.PlayersArr[v.Bullet.OffenderJoinIndex-1]
 | 
				
			||||||
				for _, obj := range collision.Objects {
 | 
									for _, obj := range collision.Objects {
 | 
				
			||||||
					defenderShape := obj.Shape.(*resolv.ConvexPolygon)
 | 
										defenderShape := obj.Shape.(*resolv.ConvexPolygon)
 | 
				
			||||||
					switch t := obj.Data.(type) {
 | 
										switch t := obj.Data.(type) {
 | 
				
			||||||
					case *PlayerDownsync:
 | 
										case *PlayerDownsync:
 | 
				
			||||||
						if v.OffenderJoinIndex == t.JoinIndex {
 | 
											if v.Bullet.OffenderJoinIndex == t.JoinIndex {
 | 
				
			||||||
							continue
 | 
												continue
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						overlapped, _, _, _ := calcPushbacks(0, 0, bulletShape, defenderShape)
 | 
											overlapped, _, _, _ := calcPushbacks(0, 0, bulletShape, defenderShape)
 | 
				
			||||||
@@ -893,18 +908,18 @@ func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(inputsBuffer *RingBuffer
 | 
				
			|||||||
						if 0 > offender.DirX {
 | 
											if 0 > offender.DirX {
 | 
				
			||||||
							xfac = -xfac
 | 
												xfac = -xfac
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						pushbackVelX, pushbackVelY := xfac*v.PushbackVelX, v.PushbackVelY
 | 
											pushbackVelX, pushbackVelY := xfac*v.Bullet.PushbackVelX, v.Bullet.PushbackVelY
 | 
				
			||||||
						atkedPlayerInNextFrame := nextRenderFramePlayers[t.JoinIndex-1]
 | 
											atkedPlayerInNextFrame := nextRenderFramePlayers[t.JoinIndex-1]
 | 
				
			||||||
						atkedPlayerInNextFrame.VelX = pushbackVelX
 | 
											atkedPlayerInNextFrame.VelX = pushbackVelX
 | 
				
			||||||
						atkedPlayerInNextFrame.VelY = pushbackVelY
 | 
											atkedPlayerInNextFrame.VelY = pushbackVelY
 | 
				
			||||||
						if v.BlowUp {
 | 
											if v.Bullet.BlowUp {
 | 
				
			||||||
							atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_BLOWN_UP1
 | 
												atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_BLOWN_UP1
 | 
				
			||||||
						} else {
 | 
											} else {
 | 
				
			||||||
							atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATKED1
 | 
												atkedPlayerInNextFrame.CharacterState = ATK_CHARACTER_STATE_ATKED1
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						oldFramesToRecover := nextRenderFramePlayers[t.JoinIndex-1].FramesToRecover
 | 
											oldFramesToRecover := nextRenderFramePlayers[t.JoinIndex-1].FramesToRecover
 | 
				
			||||||
						if v.HitStunFrames > oldFramesToRecover {
 | 
											if v.Bullet.HitStunFrames > oldFramesToRecover {
 | 
				
			||||||
							atkedPlayerInNextFrame.FramesToRecover = v.HitStunFrames
 | 
												atkedPlayerInNextFrame.FramesToRecover = v.Bullet.HitStunFrames
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					default:
 | 
										default:
 | 
				
			||||||
						addToNextRenderFrame = false
 | 
											addToNextRenderFrame = false
 | 
				
			||||||
@@ -1053,3 +1068,77 @@ func AlignPolygon2DToBoundingBox(input *Polygon2D) *Polygon2D {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return output
 | 
						return output
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewMeleeBullet(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY int32, blowUp bool, teamId int32) *MeleeBullet {
 | 
				
			||||||
 | 
						return &MeleeBullet{
 | 
				
			||||||
 | 
							Bullet: &BulletConfig{
 | 
				
			||||||
 | 
								BulletLocalId:           bulletLocalId,
 | 
				
			||||||
 | 
								OriginatedRenderFrameId: originatedRenderFrameId,
 | 
				
			||||||
 | 
								OffenderJoinIndex:       offenderJoinIndex,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								StartupFrames:      startupFrames,
 | 
				
			||||||
 | 
								CancellableStFrame: cancellableStFrame,
 | 
				
			||||||
 | 
								CancellableEdFrame: cancellableEdFrame,
 | 
				
			||||||
 | 
								ActiveFrames:       activeFrames,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								HitStunFrames:   hitStunFrames,
 | 
				
			||||||
 | 
								BlockStunFrames: blockStunFrames,
 | 
				
			||||||
 | 
								PushbackVelX:    pushbackVelX,
 | 
				
			||||||
 | 
								PushbackVelY:    pushbackVelY,
 | 
				
			||||||
 | 
								Damage:          damage,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								SelfLockVelX: selfLockVelX,
 | 
				
			||||||
 | 
								SelfLockVelY: selfLockVelY,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								HitboxOffsetX: hitboxOffsetX,
 | 
				
			||||||
 | 
								HitboxOffsetY: hitboxOffsetY,
 | 
				
			||||||
 | 
								HitboxSizeX:   hitboxSizeX,
 | 
				
			||||||
 | 
								HitboxSizeY:   hitboxSizeY,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								BlowUp: blowUp,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								TeamId: teamId,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewFireballBullet(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY int32, blowUp bool, teamId int32, virtualGridX, virtualGridY, dirX, dirY, velX, velY, speed, speciesId int32) *FireballBullet {
 | 
				
			||||||
 | 
						return &FireballBullet{
 | 
				
			||||||
 | 
							VirtualGridX: virtualGridX,
 | 
				
			||||||
 | 
							VirtualGridY: virtualGridY,
 | 
				
			||||||
 | 
							DirX:         dirX,
 | 
				
			||||||
 | 
							DirY:         dirY,
 | 
				
			||||||
 | 
							VelX:         velX,
 | 
				
			||||||
 | 
							VelY:         velY,
 | 
				
			||||||
 | 
							Speed:        speed,
 | 
				
			||||||
 | 
							SpeciesId:    speciesId,
 | 
				
			||||||
 | 
							Bullet: &BulletConfig{
 | 
				
			||||||
 | 
								BulletLocalId:           bulletLocalId,
 | 
				
			||||||
 | 
								OriginatedRenderFrameId: originatedRenderFrameId,
 | 
				
			||||||
 | 
								OffenderJoinIndex:       offenderJoinIndex,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								StartupFrames:      startupFrames,
 | 
				
			||||||
 | 
								CancellableStFrame: cancellableStFrame,
 | 
				
			||||||
 | 
								CancellableEdFrame: cancellableEdFrame,
 | 
				
			||||||
 | 
								ActiveFrames:       activeFrames,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								HitStunFrames:   hitStunFrames,
 | 
				
			||||||
 | 
								BlockStunFrames: blockStunFrames,
 | 
				
			||||||
 | 
								PushbackVelX:    pushbackVelX,
 | 
				
			||||||
 | 
								PushbackVelY:    pushbackVelY,
 | 
				
			||||||
 | 
								Damage:          damage,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								SelfLockVelX: selfLockVelX,
 | 
				
			||||||
 | 
								SelfLockVelY: selfLockVelY,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								HitboxOffsetX: hitboxOffsetX,
 | 
				
			||||||
 | 
								HitboxOffsetY: hitboxOffsetY,
 | 
				
			||||||
 | 
								HitboxSizeX:   hitboxSizeX,
 | 
				
			||||||
 | 
								HitboxSizeY:   hitboxSizeY,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								BlowUp: blowUp,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								TeamId: teamId,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,8 +61,8 @@ var Characters = map[int]*CharacterConfig{
 | 
				
			|||||||
					if skillConfig, existent1 := skills[int(currPlayerDownsync.ActiveSkillId)]; existent1 {
 | 
										if skillConfig, existent1 := skills[int(currPlayerDownsync.ActiveSkillId)]; existent1 {
 | 
				
			||||||
						switch v := skillConfig.Hits[currPlayerDownsync.ActiveSkillHit].(type) {
 | 
											switch v := skillConfig.Hits[currPlayerDownsync.ActiveSkillHit].(type) {
 | 
				
			||||||
						case *MeleeBullet:
 | 
											case *MeleeBullet:
 | 
				
			||||||
							if v.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.CancellableEdFrame {
 | 
												if v.Bullet.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.Bullet.CancellableEdFrame {
 | 
				
			||||||
								if nextSkillId, existent2 := v.CancelTransit[patternId]; existent2 {
 | 
													if nextSkillId, existent2 := v.Bullet.CancelTransit[patternId]; existent2 {
 | 
				
			||||||
									return nextSkillId
 | 
														return nextSkillId
 | 
				
			||||||
								}
 | 
													}
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
@@ -111,8 +111,8 @@ var Characters = map[int]*CharacterConfig{
 | 
				
			|||||||
					if skillConfig, existent1 := skills[int(currPlayerDownsync.ActiveSkillId)]; existent1 {
 | 
										if skillConfig, existent1 := skills[int(currPlayerDownsync.ActiveSkillId)]; existent1 {
 | 
				
			||||||
						switch v := skillConfig.Hits[currPlayerDownsync.ActiveSkillHit].(type) {
 | 
											switch v := skillConfig.Hits[currPlayerDownsync.ActiveSkillHit].(type) {
 | 
				
			||||||
						case *MeleeBullet:
 | 
											case *MeleeBullet:
 | 
				
			||||||
							if v.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.CancellableEdFrame {
 | 
												if v.Bullet.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.Bullet.CancellableEdFrame {
 | 
				
			||||||
								if nextSkillId, existent2 := v.CancelTransit[patternId]; existent2 {
 | 
													if nextSkillId, existent2 := v.Bullet.CancelTransit[patternId]; existent2 {
 | 
				
			||||||
									return nextSkillId
 | 
														return nextSkillId
 | 
				
			||||||
								}
 | 
													}
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
@@ -157,8 +157,8 @@ var Characters = map[int]*CharacterConfig{
 | 
				
			|||||||
					if skillConfig, existent1 := skills[int(currPlayerDownsync.ActiveSkillId)]; existent1 {
 | 
										if skillConfig, existent1 := skills[int(currPlayerDownsync.ActiveSkillId)]; existent1 {
 | 
				
			||||||
						switch v := skillConfig.Hits[currPlayerDownsync.ActiveSkillHit].(type) {
 | 
											switch v := skillConfig.Hits[currPlayerDownsync.ActiveSkillHit].(type) {
 | 
				
			||||||
						case *MeleeBullet:
 | 
											case *MeleeBullet:
 | 
				
			||||||
							if v.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.CancellableEdFrame {
 | 
												if v.Bullet.CancellableStFrame <= currPlayerDownsync.FramesInChState && currPlayerDownsync.FramesInChState < v.Bullet.CancellableEdFrame {
 | 
				
			||||||
								if nextSkillId, existent2 := v.CancelTransit[patternId]; existent2 {
 | 
													if nextSkillId, existent2 := v.Bullet.CancelTransit[patternId]; existent2 {
 | 
				
			||||||
									return nextSkillId
 | 
														return nextSkillId
 | 
				
			||||||
								}
 | 
													}
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
@@ -190,7 +190,7 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
		BoundChState:          ATK_CHARACTER_STATE_ATK1,
 | 
							BoundChState:          ATK_CHARACTER_STATE_ATK1,
 | 
				
			||||||
		Hits: []interface{}{
 | 
							Hits: []interface{}{
 | 
				
			||||||
			&MeleeBullet{
 | 
								&MeleeBullet{
 | 
				
			||||||
				Bullet: Bullet{
 | 
									Bullet: &BulletConfig{
 | 
				
			||||||
					StartupFrames:      int32(7),
 | 
										StartupFrames:      int32(7),
 | 
				
			||||||
					ActiveFrames:       int32(22),
 | 
										ActiveFrames:       int32(22),
 | 
				
			||||||
					HitStunFrames:      int32(13),
 | 
										HitStunFrames:      int32(13),
 | 
				
			||||||
@@ -223,7 +223,7 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
		BoundChState:          ATK_CHARACTER_STATE_ATK2,
 | 
							BoundChState:          ATK_CHARACTER_STATE_ATK2,
 | 
				
			||||||
		Hits: []interface{}{
 | 
							Hits: []interface{}{
 | 
				
			||||||
			&MeleeBullet{
 | 
								&MeleeBullet{
 | 
				
			||||||
				Bullet: Bullet{
 | 
									Bullet: &BulletConfig{
 | 
				
			||||||
					StartupFrames:      int32(18),
 | 
										StartupFrames:      int32(18),
 | 
				
			||||||
					ActiveFrames:       int32(18),
 | 
										ActiveFrames:       int32(18),
 | 
				
			||||||
					HitStunFrames:      int32(18),
 | 
										HitStunFrames:      int32(18),
 | 
				
			||||||
@@ -254,7 +254,7 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
		BoundChState:          ATK_CHARACTER_STATE_ATK3,
 | 
							BoundChState:          ATK_CHARACTER_STATE_ATK3,
 | 
				
			||||||
		Hits: []interface{}{
 | 
							Hits: []interface{}{
 | 
				
			||||||
			&MeleeBullet{
 | 
								&MeleeBullet{
 | 
				
			||||||
				Bullet: Bullet{
 | 
									Bullet: &BulletConfig{
 | 
				
			||||||
					StartupFrames:   int32(8),
 | 
										StartupFrames:   int32(8),
 | 
				
			||||||
					ActiveFrames:    int32(30),
 | 
										ActiveFrames:    int32(30),
 | 
				
			||||||
					HitStunFrames:   MAX_INT32,
 | 
										HitStunFrames:   MAX_INT32,
 | 
				
			||||||
@@ -281,7 +281,7 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
		BoundChState:          ATK_CHARACTER_STATE_ATK1,
 | 
							BoundChState:          ATK_CHARACTER_STATE_ATK1,
 | 
				
			||||||
		Hits: []interface{}{
 | 
							Hits: []interface{}{
 | 
				
			||||||
			&MeleeBullet{
 | 
								&MeleeBullet{
 | 
				
			||||||
				Bullet: Bullet{
 | 
									Bullet: &BulletConfig{
 | 
				
			||||||
					StartupFrames:      int32(7),
 | 
										StartupFrames:      int32(7),
 | 
				
			||||||
					ActiveFrames:       int32(22),
 | 
										ActiveFrames:       int32(22),
 | 
				
			||||||
					HitStunFrames:      int32(13),
 | 
										HitStunFrames:      int32(13),
 | 
				
			||||||
@@ -314,7 +314,7 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
		BoundChState:          ATK_CHARACTER_STATE_ATK2,
 | 
							BoundChState:          ATK_CHARACTER_STATE_ATK2,
 | 
				
			||||||
		Hits: []interface{}{
 | 
							Hits: []interface{}{
 | 
				
			||||||
			&MeleeBullet{
 | 
								&MeleeBullet{
 | 
				
			||||||
				Bullet: Bullet{
 | 
									Bullet: &BulletConfig{
 | 
				
			||||||
					StartupFrames:      int32(18),
 | 
										StartupFrames:      int32(18),
 | 
				
			||||||
					ActiveFrames:       int32(18),
 | 
										ActiveFrames:       int32(18),
 | 
				
			||||||
					HitStunFrames:      int32(18),
 | 
										HitStunFrames:      int32(18),
 | 
				
			||||||
@@ -345,7 +345,7 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
		BoundChState:          ATK_CHARACTER_STATE_ATK3,
 | 
							BoundChState:          ATK_CHARACTER_STATE_ATK3,
 | 
				
			||||||
		Hits: []interface{}{
 | 
							Hits: []interface{}{
 | 
				
			||||||
			&MeleeBullet{
 | 
								&MeleeBullet{
 | 
				
			||||||
				Bullet: Bullet{
 | 
									Bullet: &BulletConfig{
 | 
				
			||||||
					StartupFrames:   int32(8),
 | 
										StartupFrames:   int32(8),
 | 
				
			||||||
					ActiveFrames:    int32(28),
 | 
										ActiveFrames:    int32(28),
 | 
				
			||||||
					HitStunFrames:   MAX_INT32,
 | 
										HitStunFrames:   MAX_INT32,
 | 
				
			||||||
@@ -372,7 +372,7 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
		BoundChState:          ATK_CHARACTER_STATE_ATK1,
 | 
							BoundChState:          ATK_CHARACTER_STATE_ATK1,
 | 
				
			||||||
		Hits: []interface{}{
 | 
							Hits: []interface{}{
 | 
				
			||||||
			&MeleeBullet{
 | 
								&MeleeBullet{
 | 
				
			||||||
				Bullet: Bullet{
 | 
									Bullet: &BulletConfig{
 | 
				
			||||||
					StartupFrames:      int32(7),
 | 
										StartupFrames:      int32(7),
 | 
				
			||||||
					ActiveFrames:       int32(22),
 | 
										ActiveFrames:       int32(22),
 | 
				
			||||||
					HitStunFrames:      int32(13),
 | 
										HitStunFrames:      int32(13),
 | 
				
			||||||
@@ -405,7 +405,7 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
		BoundChState:          ATK_CHARACTER_STATE_ATK2,
 | 
							BoundChState:          ATK_CHARACTER_STATE_ATK2,
 | 
				
			||||||
		Hits: []interface{}{
 | 
							Hits: []interface{}{
 | 
				
			||||||
			&MeleeBullet{
 | 
								&MeleeBullet{
 | 
				
			||||||
				Bullet: Bullet{
 | 
									Bullet: &BulletConfig{
 | 
				
			||||||
					StartupFrames:      int32(18),
 | 
										StartupFrames:      int32(18),
 | 
				
			||||||
					ActiveFrames:       int32(18),
 | 
										ActiveFrames:       int32(18),
 | 
				
			||||||
					HitStunFrames:      int32(18),
 | 
										HitStunFrames:      int32(18),
 | 
				
			||||||
@@ -436,7 +436,7 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
		BoundChState:          ATK_CHARACTER_STATE_ATK3,
 | 
							BoundChState:          ATK_CHARACTER_STATE_ATK3,
 | 
				
			||||||
		Hits: []interface{}{
 | 
							Hits: []interface{}{
 | 
				
			||||||
			&MeleeBullet{
 | 
								&MeleeBullet{
 | 
				
			||||||
				Bullet: Bullet{
 | 
									Bullet: &BulletConfig{
 | 
				
			||||||
					StartupFrames:   int32(7),
 | 
										StartupFrames:   int32(7),
 | 
				
			||||||
					ActiveFrames:    int32(30),
 | 
										ActiveFrames:    int32(30),
 | 
				
			||||||
					HitStunFrames:   MAX_INT32,
 | 
										HitStunFrames:   MAX_INT32,
 | 
				
			||||||
@@ -464,8 +464,8 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
		Hits: []interface{}{
 | 
							Hits: []interface{}{
 | 
				
			||||||
			&FireballBullet{
 | 
								&FireballBullet{
 | 
				
			||||||
				SpeciesId: int32(1),
 | 
									SpeciesId: int32(1),
 | 
				
			||||||
				Speed:     int32(float64(8) * WORLD_TO_VIRTUAL_GRID_RATIO),
 | 
									Speed:     int32(float64(5) * WORLD_TO_VIRTUAL_GRID_RATIO),
 | 
				
			||||||
				Bullet: Bullet{
 | 
									Bullet: &BulletConfig{
 | 
				
			||||||
					StartupFrames:   int32(15),
 | 
										StartupFrames:   int32(15),
 | 
				
			||||||
					ActiveFrames:    MAX_INT32,
 | 
										ActiveFrames:    MAX_INT32,
 | 
				
			||||||
					HitStunFrames:   int32(15),
 | 
										HitStunFrames:   int32(15),
 | 
				
			||||||
@@ -475,7 +475,7 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
					SelfLockVelY:    NO_LOCK_VEL,
 | 
										SelfLockVelY:    NO_LOCK_VEL,
 | 
				
			||||||
					PushbackVelX:    int32(float64(2) * WORLD_TO_VIRTUAL_GRID_RATIO),
 | 
										PushbackVelX:    int32(float64(2) * WORLD_TO_VIRTUAL_GRID_RATIO),
 | 
				
			||||||
					PushbackVelY:    int32(0),
 | 
										PushbackVelY:    int32(0),
 | 
				
			||||||
					HitboxOffsetX:   int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
 | 
										HitboxOffsetX:   int32(float64(18) * WORLD_TO_VIRTUAL_GRID_RATIO),
 | 
				
			||||||
					HitboxOffsetY:   int32(float64(5) * WORLD_TO_VIRTUAL_GRID_RATIO),
 | 
										HitboxOffsetY:   int32(float64(5) * WORLD_TO_VIRTUAL_GRID_RATIO),
 | 
				
			||||||
					HitboxSizeX:     int32(float64(48) * WORLD_TO_VIRTUAL_GRID_RATIO),
 | 
										HitboxSizeX:     int32(float64(48) * WORLD_TO_VIRTUAL_GRID_RATIO),
 | 
				
			||||||
					HitboxSizeY:     int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
 | 
										HitboxSizeY:     int32(float64(32) * WORLD_TO_VIRTUAL_GRID_RATIO),
 | 
				
			||||||
@@ -491,7 +491,7 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
		BoundChState:          ATK_CHARACTER_STATE_ATK5,
 | 
							BoundChState:          ATK_CHARACTER_STATE_ATK5,
 | 
				
			||||||
		Hits: []interface{}{
 | 
							Hits: []interface{}{
 | 
				
			||||||
			&MeleeBullet{
 | 
								&MeleeBullet{
 | 
				
			||||||
				Bullet: Bullet{
 | 
									Bullet: &BulletConfig{
 | 
				
			||||||
					StartupFrames:   int32(3),
 | 
										StartupFrames:   int32(3),
 | 
				
			||||||
					ActiveFrames:    int32(25),
 | 
										ActiveFrames:    int32(25),
 | 
				
			||||||
					HitStunFrames:   MAX_INT32,
 | 
										HitStunFrames:   MAX_INT32,
 | 
				
			||||||
@@ -518,7 +518,7 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
		BoundChState:          ATK_CHARACTER_STATE_INAIR_ATK1,
 | 
							BoundChState:          ATK_CHARACTER_STATE_INAIR_ATK1,
 | 
				
			||||||
		Hits: []interface{}{
 | 
							Hits: []interface{}{
 | 
				
			||||||
			&MeleeBullet{
 | 
								&MeleeBullet{
 | 
				
			||||||
				Bullet: Bullet{
 | 
									Bullet: &BulletConfig{
 | 
				
			||||||
					StartupFrames:   int32(3),
 | 
										StartupFrames:   int32(3),
 | 
				
			||||||
					ActiveFrames:    int32(20),
 | 
										ActiveFrames:    int32(20),
 | 
				
			||||||
					HitStunFrames:   int32(18),
 | 
										HitStunFrames:   int32(18),
 | 
				
			||||||
@@ -544,7 +544,7 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
		BoundChState:          ATK_CHARACTER_STATE_INAIR_ATK1,
 | 
							BoundChState:          ATK_CHARACTER_STATE_INAIR_ATK1,
 | 
				
			||||||
		Hits: []interface{}{
 | 
							Hits: []interface{}{
 | 
				
			||||||
			&MeleeBullet{
 | 
								&MeleeBullet{
 | 
				
			||||||
				Bullet: Bullet{
 | 
									Bullet: &BulletConfig{
 | 
				
			||||||
					StartupFrames:   int32(3),
 | 
										StartupFrames:   int32(3),
 | 
				
			||||||
					ActiveFrames:    int32(10),
 | 
										ActiveFrames:    int32(10),
 | 
				
			||||||
					HitStunFrames:   int32(15),
 | 
										HitStunFrames:   int32(15),
 | 
				
			||||||
@@ -570,7 +570,7 @@ var skills = map[int]*Skill{
 | 
				
			|||||||
		BoundChState:          ATK_CHARACTER_STATE_INAIR_ATK1,
 | 
							BoundChState:          ATK_CHARACTER_STATE_INAIR_ATK1,
 | 
				
			||||||
		Hits: []interface{}{
 | 
							Hits: []interface{}{
 | 
				
			||||||
			&MeleeBullet{
 | 
								&MeleeBullet{
 | 
				
			||||||
				Bullet: Bullet{
 | 
									Bullet: &BulletConfig{
 | 
				
			||||||
					StartupFrames:   int32(3),
 | 
										StartupFrames:   int32(3),
 | 
				
			||||||
					ActiveFrames:    int32(20),
 | 
										ActiveFrames:    int32(20),
 | 
				
			||||||
					HitStunFrames:   int32(18),
 | 
										HitStunFrames:   int32(18),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,6 +34,8 @@ type PlayerDownsync struct {
 | 
				
			|||||||
	CharacterState    int32
 | 
						CharacterState    int32
 | 
				
			||||||
	InAir             bool
 | 
						InAir             bool
 | 
				
			||||||
	OnWall            bool
 | 
						OnWall            bool
 | 
				
			||||||
 | 
						OnWallNormX       int32
 | 
				
			||||||
 | 
						OnWallNormY       int32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ActiveSkillId  int32
 | 
						ActiveSkillId  int32
 | 
				
			||||||
	ActiveSkillHit int32
 | 
						ActiveSkillHit int32
 | 
				
			||||||
@@ -42,9 +44,6 @@ type PlayerDownsync struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	BulletTeamId      int32
 | 
						BulletTeamId      int32
 | 
				
			||||||
	ChCollisionTeamId int32 // not the same as "BulletTeamId", because even in the same team, we should allow inter-character collisions
 | 
						ChCollisionTeamId int32 // not the same as "BulletTeamId", because even in the same team, we should allow inter-character collisions
 | 
				
			||||||
 | 
					 | 
				
			||||||
    OnWallNormX int32
 | 
					 | 
				
			||||||
    OnWallNormY int32
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type InputFrameDecoded struct {
 | 
					type InputFrameDecoded struct {
 | 
				
			||||||
@@ -63,7 +62,7 @@ type Barrier struct {
 | 
				
			|||||||
	Boundary *Polygon2D
 | 
						Boundary *Polygon2D
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Bullet struct {
 | 
					type BulletConfig struct {
 | 
				
			||||||
	BulletLocalId int32 // for referencing cached nodes in frontend rendering
 | 
						BulletLocalId int32 // for referencing cached nodes in frontend rendering
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// for offender
 | 
						// for offender
 | 
				
			||||||
@@ -97,7 +96,7 @@ type Bullet struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type MeleeBullet struct {
 | 
					type MeleeBullet struct {
 | 
				
			||||||
	Bullet
 | 
						Bullet *BulletConfig
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type FireballBullet struct {
 | 
					type FireballBullet struct {
 | 
				
			||||||
@@ -109,7 +108,7 @@ type FireballBullet struct {
 | 
				
			|||||||
	VelY         int32
 | 
						VelY         int32
 | 
				
			||||||
	Speed        int32
 | 
						Speed        int32
 | 
				
			||||||
	SpeciesId    int32
 | 
						SpeciesId    int32
 | 
				
			||||||
	Bullet
 | 
						Bullet       *BulletConfig
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Skill struct {
 | 
					type Skill struct {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,77 +73,11 @@ func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewMeleeBulletJs(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY int32, blowUp bool, teamId int32) *js.Object {
 | 
					func NewMeleeBulletJs(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY int32, blowUp bool, teamId int32) *js.Object {
 | 
				
			||||||
	return js.MakeWrapper(&MeleeBullet{
 | 
						return js.MakeWrapper(NewMeleeBullet(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY, blowUp, teamId))
 | 
				
			||||||
		Bullet: Bullet{
 | 
					 | 
				
			||||||
			BulletLocalId:           bulletLocalId,
 | 
					 | 
				
			||||||
			OriginatedRenderFrameId: originatedRenderFrameId,
 | 
					 | 
				
			||||||
			OffenderJoinIndex:       offenderJoinIndex,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			StartupFrames:      startupFrames,
 | 
					 | 
				
			||||||
			CancellableStFrame: cancellableStFrame,
 | 
					 | 
				
			||||||
			CancellableEdFrame: cancellableEdFrame,
 | 
					 | 
				
			||||||
			ActiveFrames:       activeFrames,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			HitStunFrames:   hitStunFrames,
 | 
					 | 
				
			||||||
			BlockStunFrames: blockStunFrames,
 | 
					 | 
				
			||||||
			PushbackVelX:    pushbackVelX,
 | 
					 | 
				
			||||||
			PushbackVelY:    pushbackVelY,
 | 
					 | 
				
			||||||
			Damage:          damage,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			SelfLockVelX: selfLockVelX,
 | 
					 | 
				
			||||||
			SelfLockVelY: selfLockVelY,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			HitboxOffsetX: hitboxOffsetX,
 | 
					 | 
				
			||||||
			HitboxOffsetY: hitboxOffsetY,
 | 
					 | 
				
			||||||
			HitboxSizeX:   hitboxSizeX,
 | 
					 | 
				
			||||||
			HitboxSizeY:   hitboxSizeY,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			BlowUp: blowUp,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			TeamId: teamId,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewFireballBulletJs(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY int32, blowUp bool, teamId int32, virtualGridX, virtualGridY, dirX, dirY, velX, velY, speed, speciesId int32) *js.Object {
 | 
					func NewFireballBulletJs(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY int32, blowUp bool, teamId int32, virtualGridX, virtualGridY, dirX, dirY, velX, velY, speed, speciesId int32) *js.Object {
 | 
				
			||||||
	return js.MakeWrapper(&FireballBullet{
 | 
						return js.MakeWrapper(NewFireballBullet(bulletLocalId, originatedRenderFrameId, offenderJoinIndex, startupFrames, cancellableStFrame, cancellableEdFrame, activeFrames, hitStunFrames, blockStunFrames, pushbackVelX, pushbackVelY, damage, selfLockVelX, selfLockVelY, hitboxOffsetX, hitboxOffsetY, hitboxSizeX, hitboxSizeY, blowUp, teamId, virtualGridX, virtualGridY, dirX, dirY, velX, velY, speed, speciesId))
 | 
				
			||||||
		VirtualGridX: virtualGridX,
 | 
					 | 
				
			||||||
		VirtualGridY: virtualGridY,
 | 
					 | 
				
			||||||
		DirX:         dirX,
 | 
					 | 
				
			||||||
		DirY:         dirY,
 | 
					 | 
				
			||||||
		VelX:         velX,
 | 
					 | 
				
			||||||
		VelY:         velY,
 | 
					 | 
				
			||||||
		Speed:        speed,
 | 
					 | 
				
			||||||
		SpeciesId:    speciesId,
 | 
					 | 
				
			||||||
		Bullet: Bullet{
 | 
					 | 
				
			||||||
			BulletLocalId:           bulletLocalId,
 | 
					 | 
				
			||||||
			OriginatedRenderFrameId: originatedRenderFrameId,
 | 
					 | 
				
			||||||
			OffenderJoinIndex:       offenderJoinIndex,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			StartupFrames:      startupFrames,
 | 
					 | 
				
			||||||
			CancellableStFrame: cancellableStFrame,
 | 
					 | 
				
			||||||
			CancellableEdFrame: cancellableEdFrame,
 | 
					 | 
				
			||||||
			ActiveFrames:       activeFrames,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			HitStunFrames:   hitStunFrames,
 | 
					 | 
				
			||||||
			BlockStunFrames: blockStunFrames,
 | 
					 | 
				
			||||||
			PushbackVelX:    pushbackVelX,
 | 
					 | 
				
			||||||
			PushbackVelY:    pushbackVelY,
 | 
					 | 
				
			||||||
			Damage:          damage,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			SelfLockVelX: selfLockVelX,
 | 
					 | 
				
			||||||
			SelfLockVelY: selfLockVelY,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			HitboxOffsetX: hitboxOffsetX,
 | 
					 | 
				
			||||||
			HitboxOffsetY: hitboxOffsetY,
 | 
					 | 
				
			||||||
			HitboxSizeX:   hitboxSizeX,
 | 
					 | 
				
			||||||
			HitboxSizeY:   hitboxSizeY,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			BlowUp: blowUp,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			TeamId: teamId,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewNpcPatrolCue(flAct, frAct uint64, x, y float64) *js.Object {
 | 
					func NewNpcPatrolCue(flAct, frAct uint64, x, y float64) *js.Object {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user