UnclePunch
Smash Ace
- Joined
- Nov 9, 2014
- Messages
- 673
Been on a game mode kick the last 2 days. This code replaces Giant Melee with a new game mode that despawns all but the first 2 present characters, and respawns the next available despawned character upon someone dying. The surviving player currently keeps their percent upon KO'ing a player, but I'm open to changing this if I see a demand for it.
Once again, this uses a GObjProc to accomplish the logic. There are no hooks in the game engine and its handled from outside, meaning the code is entirely confined to Giant Melee!
https://gfycat.com/InsidiousOpulentBergerpicard
Once again, this uses a GObjProc to accomplish the logic. There are no hooks in the game engine and its handled from outside, meaning the code is entirely confined to Giant Melee!
Code:
$One Stock Rotations v1.1 [UnclePunch]
*Replaces Giant Melee
C21B9090 00000080
808D8840 38840F98
48000011 7CA802A6
90A40044 480003E4
4E800021 7C0802A6
90010004 9421FF00
BE810008 38600016
38800017 38A00000
3D808039 618C01F0
7D8903A6 4E800421
7C7F1B78 38600040
3D808037 618CF1E4
7D8903A6 4E800421
7C7E1B78 7FC3F378
38800040 3D808000
618CC160 7D8903A6
4E800421 7FE3FB78
3880000E 3CA08037
60A5F1B0 7FC6F378
3D808039 618C0B68
7D8903A6 4E800421
7FE3FB78 48000031
7C8802A6 38A00017
3D808038 618CFD54
7D8903A6 4E800421
BA810008 80010104
38210100 7C0803A6
4E800020 4E800021
7C0802A6 90010004
9421FF00 BE810008
7C7F1B78 83DF002C
887E0000 2C030000
4182000C 2C030001
41820134 3D808016
618CB558 7D8903A6
4E800421 2C030003
4080001C 7FE3FB78
3D808039 618C0228
7D8903A6 4E800421
480002B4 3BA00000
3B800000 7FA3EB78
3D808003 618C22C0
7D8903A6 4E800421
2C030002 4082001C
387E0001 7FBC19AE
9BBE0003 3B9C0001
2C1C0002 408000B0
3BBD0001 2C1D0006
4180FFC4 7FA3EB78
3D808003 618C22C0
7D8903A6 4E800421
2C030002 40820088
7FA3EB78 3D808003
618C4110 7D8903A6
4E800421 7C7B1B78
3D80800B 618CFD04
7D8903A6 4E800421
807B002C 88632222
5460F7FF 4182002C
7FA3EB78 38800001
3D808003 618C418C
7D8903A6 4E800421
3D80800B 618CFD04
7D8903A6 4E800421
3C60804A 606310C8
1C9D0064 7C632214
88830010 38A00001
50A43E30 50A43672
98830010 3BBD0001
2C1D0006 4180FF58
38600001 987E0000
480001B4 3B800000
387E0001 7FBC18AE
7FA3EB78 3D808003
618C4110 7D8903A6
4E800421 7C7B1B78
8063002C 8883221F
548406F7 40820170
8883221D 54840739
40820164 88832219
54840673 41820158
80830010 2C04000C
4182014C 2C04000D
41820144 2C040004
41820018 2C040005
41820010 2C040006
41820008 4800001C
7F63DB78 3D80800D
618C3E40 7D8903A6
4E800421 48000110
807B002C 80832340
2C040001 41810100
6B830001 389E0001
7F2320AE 8B1E0003
7F1AC378 480000D0
7F43D378 3D808003
618C22C0 7D8903A6
4E800421 2C030002
408200B4 7C1AE800
418200AC 7C1AC800
418200A4 7F43D378
3D808003 618C3BD8
7D8903A6 4E800421
2C030000 40810088
7F43D378 3D808003
618C4110 7D8903A6
4E800421 38800001
3D80800B 618CFD9C
7D8903A6 4E800421
387E0001 7F5C19AE
9B5E0003 7F63DB78
3D80800B 618CFD04
7D8903A6 4E800421
809B002C 88642222
5460F7FF 41820048
8864000C 38800001
3D808003 618C418C
7D8903A6 4E800421
3D80800B 618CFD04
7D8903A6 4E800421
4800001C 3B5A0001
2C1A0006 41800008
3B400000 7C1AC000
4082FF20 3B9C0001
2C1C0002 4180FE5C
48000004 BA810008
80010104 38210100
7C0803A6 4E800020
38C00000 00000000
Code:
#To be inserted at 801b9090
.include "../Common.s"
#Store Pointer to onStartMelee function
lwz r4, -0x77C0 (r13)
addi r4, r4, 3992
bl Rotations_Init
mflr r5
stw r5,0x44(r4)
b InjectionExit
#region Rotations_Init
Rotations_Init:
blrl
.set REG_GObj,31
.set REG_Data,30
.set DataSize,64
backup
#Create GObj
li r3,22
li r4,23
li r5,0
branchl r12,GObj_Create
mr REG_GObj,r3
#Alloc Mem
li r3,DataSize
branchl r12,HSD_MemAlloc
mr REG_Data,r3
#Zero Data
mr r3,REG_Data
li r4,DataSize
branchl r12,ZeroAreaLength
#Attach Data
mr r3,REG_GObj
li r4,14
load r5,HSD_Free
mr r6,REG_Data
branchl r12,GObj_Initialize
#Attach Process
mr r3,REG_GObj
bl Rotations_Think
mflr r4
li r5,23
branchl r12,GObj_SchedulePerFrameFunction
Rotations_InitExit:
restore
blr
#endregion
#region Rotations_Think
Rotations_Think:
blrl
#Registers
.set REG_GObj,31
.set REG_GObjData,30
#Data Offsets
.set GameState,0x0 #byte
.set P1Slot,0x1 #byte
.set P2Slot,0x2 #byte
.set LastPlayerSpawned,0x3 #byte
#Definitions
#GameState
.set FirstFrame,0x0
.set InProgress,0x1
#Constants
.set FreezeFrames, 1 * 60
backup
#Init Pointers
mr REG_GObj,r3
lwz REG_GObjData,0x2C(REG_GObj)
#Check state of game
lbz r3,GameState(REG_GObjData)
cmpwi r3,FirstFrame
beq Rotations_Think_FirstFrame
cmpwi r3,InProgress
beq Rotations_Think_InProgress
#region FirstFrame
Rotations_Think_FirstFrame:
#Ensure over 2 players are present
branchl r12,0x8016b558
cmpwi r3,3
bge Rotations_Think_FirstFrameContinue
#Destroy Think Function
mr r3,REG_GObj
branchl r12,0x80390228
b Rotations_ThinkExit
Rotations_Think_FirstFrameContinue:
.set REG_LoopCount,29
.set REG_PlayerSlotIndex,28
#Init Loop
li REG_LoopCount,0
li REG_PlayerSlotIndex,0
Rotations_Think_FirstFrameLoop:
#Check Players Presence
mr r3,REG_LoopCount
branchl r12,0x800322c0
cmpwi r3,0x2
bne Rotations_Think_FirstFrameIncLoop
#Player exists, store to data
addi r3,REG_GObjData,P1Slot
stbx REG_LoopCount,REG_PlayerSlotIndex,r3
#Store as last player spawned
stb REG_LoopCount,LastPlayerSpawned(REG_GObjData)
#Now do next player
addi REG_PlayerSlotIndex,REG_PlayerSlotIndex,1
#Check if finished doing both players
cmpwi REG_PlayerSlotIndex,2
bge Rotations_Think_FirstFrameSleepRemainingPlayersIncLoop
Rotations_Think_FirstFrameIncLoop:
addi REG_LoopCount,REG_LoopCount,1
cmpwi REG_LoopCount,6
blt Rotations_Think_FirstFrameLoop
#Now sleep the other players
Rotations_Think_FirstFrameSleepRemainingPlayersLoop:
.set REG_PlayerGObj,27
#Check Players Presence
mr r3,REG_LoopCount
branchl r12,0x800322c0
cmpwi r3,0x2
bne Rotations_Think_FirstFrameSleepRemainingPlayersIncLoop
#Get players GObj
mr r3,REG_LoopCount
branchl r12,0x80034110
mr REG_PlayerGObj,r3
#Sleep player
branchl r12,0x800bfd04
#Check if they have a follower
lwz r3,0x2C(REG_PlayerGObj)
lbz r3,0x2222(r3)
rlwinm. r0, r3, 30, 31, 31
beq Rotations_Think_FirstFrameSleepRemainingPlayers_DestroyHUD
#Get Follower GObj
mr r3,REG_LoopCount
li r4,1
branchl r12,0x8003418c
#SLeep them as well
branchl r12,0x800bfd04
Rotations_Think_FirstFrameSleepRemainingPlayers_DestroyHUD:
#Destroy their percent HUD
load r3,0x804a10c8
mulli r4,REG_LoopCount,100
add r3,r3,r4
lbz r4, 0x0010 (r3)
li r5,1
rlwimi r4,r5,7,24,24
rlwimi r4,r5,6,25,25
stb r4, 0x0010 (r3)
Rotations_Think_FirstFrameSleepRemainingPlayersIncLoop:
addi REG_LoopCount,REG_LoopCount,1
cmpwi REG_LoopCount,6
blt Rotations_Think_FirstFrameSleepRemainingPlayersLoop
#Change state to every frame
li r3,InProgress
stb r3,GameState(REG_GObjData)
b Rotations_ThinkExit
#endregion
#region InProgress
Rotations_Think_InProgress:
#Check For Dead Players
.set REG_PlayerSlot,29
.set REG_PlayerSlotIndex,28
.set REG_PlayerGObj,27
#Init Loop
li REG_PlayerSlotIndex,0
#################################
## Check For Dead Players Loop ##
#################################
Rotations_Think_InProgressLoop:
#Get Players Slot
addi r3,REG_GObjData,P1Slot
lbzx REG_PlayerSlot,REG_PlayerSlotIndex,r3
#Get Players GObj
mr r3,REG_PlayerSlot
branchl r12,0x80034110
mr REG_PlayerGObj,r3
lwz r3,0x2C(r3)
#Check If Player is still active (not sleep)
lbz r4,0x221F(r3)
rlwinm. r4,r4,0,27,27
bne Rotations_Think_InProgressIncLoop
#Check if READY,GO is over
lbz r4,0x221D(r3)
rlwinm. r4,r4,0,28,28
bne Rotations_Think_InProgressIncLoop
#Check if Blastzone code is being skipped
lbz r4,0x2219(r3)
rlwinm. r4,r4,0,25,25
beq Rotations_Think_InProgressIncLoop
#Rebirth gets here too, check if NOT rebirth/rebirthWait
lwz r4,0x10(r3)
cmpwi r4,ASID_Rebirth
beq Rotations_Think_InProgressIncLoop
cmpwi r4,ASID_RebirthWait
beq Rotations_Think_InProgressIncLoop
#If in any Star KO State, enter them into DeadUp
cmpwi r4,ASID_DeadUpStar
beq Rotations_Think_InProgressEnterDeadUp
cmpwi r4,ASID_DeadUpStarIce
beq Rotations_Think_InProgressEnterDeadUp
cmpwi r4,ASID_DeadUpFall
beq Rotations_Think_InProgressEnterDeadUp
b Rotations_Think_InProgressCheckDeadFrame
Rotations_Think_InProgressEnterDeadUp:
#Enter DeadUp
mr r3,REG_PlayerGObj
branchl r12,0x800d3e40
b Rotations_Think_InProgressIncLoop
Rotations_Think_InProgressCheckDeadFrame:
#Here we know the player is in a dead state
#Ensure he is in frame X of the dead animation
lwz r3,0x2C(REG_PlayerGObj)
lwz r4,0x2340(r3)
cmpwi r4,1
bgt Rotations_Think_InProgressIncLoop
#################################
## Search For Next Player Loop ##
#################################
Rotations_Think_InProgressSearchForNextPlayer:
.set REG_LoopCount,26
.set REG_OtherPlayerSlot,25
.set REG_LastPlayerSpawned,24
#Get other player
xori r3,REG_PlayerSlotIndex,0x1
addi r4,REG_GObjData,P1Slot
lbzx REG_OtherPlayerSlot,r3,r4
#Loop starts at LastPlayerSpawned+1
lbz REG_LastPlayerSpawned,LastPlayerSpawned(REG_GObjData)
mr REG_LoopCount,REG_LastPlayerSpawned
b Rotations_Think_InProgressSearchForNextPlayerIncLoop
Rotations_Think_InProgressSearchForNextPlayerLoop:
#Player who just died is in REG_PlayerSlot
#Player who is alive is in REG_OtherPlayerSlot
#Check if player is present
mr r3,REG_LoopCount
branchl r12,0x800322c0
cmpwi r3,0x2
bne Rotations_Think_InProgressSearchForNextPlayerIncLoop
#Ensure this isnt the player who just died
cmpw REG_LoopCount,REG_PlayerSlot
beq Rotations_Think_InProgressSearchForNextPlayerIncLoop
#Ensure this isnt the other player
cmpw REG_LoopCount,REG_OtherPlayerSlot
beq Rotations_Think_InProgressSearchForNextPlayerIncLoop
#This is a unique player, check if they have stock remainings
mr r3,REG_LoopCount
branchl r12,0x80033bd8
cmpwi r3,0
ble Rotations_Think_InProgressSearchForNextPlayerIncLoop
#Get GObj First
mr r3,REG_LoopCount
branchl r12,0x80034110
#Respawn
li r4,0x1
branchl r12,0x800bfd9c
#Save their slot to the GObjData
addi r3,REG_GObjData,P1Slot
stbx REG_LoopCount,REG_PlayerSlotIndex,r3
#Save this as the last player spawned
stb REG_LoopCount,LastPlayerSpawned(REG_GObjData)
#Now enter the recently deceased player into perm sleep
mr r3,REG_PlayerGObj
branchl r12,0x800bfd04
#Check if they have a follower
lwz r4,0x2C(REG_PlayerGObj)
lbz r3,0x2222(r4)
rlwinm. r0, r3, 30, 31, 31
beq Rotations_Think_InProgressIncLoop
#Get Follower GObj
lbz r3,0xC(r4)
li r4,1
branchl r12,0x8003418c
#SLeep them as well
branchl r12,0x800bfd04
b Rotations_Think_InProgressIncLoop
Rotations_Think_InProgressSearchForNextPlayerIncLoop:
addi REG_LoopCount,REG_LoopCount,1
cmpwi REG_LoopCount,6
blt Rotations_Think_InProgressSearchForNextPlayerIncLoopCheckIfDone
#Player count is over 6, loop back to 0
li REG_LoopCount,0
Rotations_Think_InProgressSearchForNextPlayerIncLoopCheckIfDone:
#Now check if we did a full loop
cmpw REG_LoopCount,REG_LastPlayerSpawned
bne Rotations_Think_InProgressSearchForNextPlayerLoop
#If we get here, no other players are reported as alive, so do nothing for normal respawn behvior
Rotations_Think_InProgressIncLoop:
addi REG_PlayerSlotIndex,REG_PlayerSlotIndex,1
cmpwi REG_PlayerSlotIndex,2
blt Rotations_Think_InProgressLoop
#Neither player is dead, exit think function
b Rotations_ThinkExit
#endregion
Rotations_ThinkExit:
restore
blr
#endregion
InjectionExit:
li r6,0
Last edited: