@@ -42,6 +42,7 @@ sound/**/*.bin
|
|||||||
sound/songs/midi/*.s
|
sound/songs/midi/*.s
|
||||||
src/*.s
|
src/*.s
|
||||||
src/data/items.h
|
src/data/items.h
|
||||||
|
src/data/wild_encounters.h
|
||||||
tags
|
tags
|
||||||
tools/agbcc
|
tools/agbcc
|
||||||
tools/binutils
|
tools/binutils
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ ELF = $(ROM:.gba=.elf)
|
|||||||
MAP = $(ROM:.gba=.map)
|
MAP = $(ROM:.gba=.map)
|
||||||
|
|
||||||
C_SUBDIR = src
|
C_SUBDIR = src
|
||||||
|
DATA_C_SUBDIR = src/data
|
||||||
ASM_SUBDIR = asm
|
ASM_SUBDIR = asm
|
||||||
DATA_ASM_SUBDIR = data
|
DATA_ASM_SUBDIR = data
|
||||||
SONG_SUBDIR = sound/songs
|
SONG_SUBDIR = sound/songs
|
||||||
|
|||||||
@@ -1725,7 +1725,7 @@ sub_806D5E8: @ 806D5E8
|
|||||||
lsls r0, 24
|
lsls r0, 24
|
||||||
cmp r0, 0
|
cmp r0, 0
|
||||||
bne _0806D658
|
bne _0806D658
|
||||||
bl sub_80830B8
|
bl UpdateRepelCounter
|
||||||
lsls r0, 24
|
lsls r0, 24
|
||||||
lsrs r0, 24
|
lsrs r0, 24
|
||||||
cmp r0, 0x1
|
cmp r0, 0x1
|
||||||
@@ -1956,7 +1956,7 @@ _0806D7E2:
|
|||||||
thumb_func_start RestartWildEncounterImmunitySteps
|
thumb_func_start RestartWildEncounterImmunitySteps
|
||||||
RestartWildEncounterImmunitySteps: @ 806D7E8
|
RestartWildEncounterImmunitySteps: @ 806D7E8
|
||||||
push {lr}
|
push {lr}
|
||||||
bl sub_80832D4
|
bl ResetEncounterRateModifiers
|
||||||
pop {r0}
|
pop {r0}
|
||||||
bx r0
|
bx r0
|
||||||
thumb_func_end RestartWildEncounterImmunitySteps
|
thumb_func_end RestartWildEncounterImmunitySteps
|
||||||
@@ -1964,7 +1964,7 @@ RestartWildEncounterImmunitySteps: @ 806D7E8
|
|||||||
thumb_func_start is_it_battle_time_3
|
thumb_func_start is_it_battle_time_3
|
||||||
is_it_battle_time_3: @ 806D7F4
|
is_it_battle_time_3: @ 806D7F4
|
||||||
push {lr}
|
push {lr}
|
||||||
bl sub_80833B0
|
bl TryStandardWildEncounter
|
||||||
lsls r0, 24
|
lsls r0, 24
|
||||||
lsrs r0, 24
|
lsrs r0, 24
|
||||||
pop {r1}
|
pop {r1}
|
||||||
|
|||||||
@@ -4481,7 +4481,7 @@ sub_805D508: @ 805D508
|
|||||||
ldrh r0, [r4, 0x8]
|
ldrh r0, [r4, 0x8]
|
||||||
adds r0, 0x1
|
adds r0, 0x1
|
||||||
strh r0, [r4, 0x8]
|
strh r0, [r4, 0x8]
|
||||||
bl sub_8082F78
|
bl DoesCurrentMapHaveFishingMons
|
||||||
lsls r0, 24
|
lsls r0, 24
|
||||||
cmp r0, 0
|
cmp r0, 0
|
||||||
beq _0805D53A
|
beq _0805D53A
|
||||||
@@ -4791,7 +4791,7 @@ _0805D788:
|
|||||||
ldrh r0, [r5, 0x26]
|
ldrh r0, [r5, 0x26]
|
||||||
lsls r0, 24
|
lsls r0, 24
|
||||||
lsrs r0, 24
|
lsrs r0, 24
|
||||||
bl sub_8082FB0
|
bl FishingWildEncounter
|
||||||
ldr r0, _0805D7BC @ =sub_805D304
|
ldr r0, _0805D7BC @ =sub_805D304
|
||||||
bl FindTaskIdByFunc
|
bl FindTaskIdByFunc
|
||||||
lsls r0, 24
|
lsls r0, 24
|
||||||
|
|||||||
+3
-3
@@ -198,8 +198,8 @@ _08081C8C:
|
|||||||
_08081C98: .4byte gUnknown_83C7248
|
_08081C98: .4byte gUnknown_83C7248
|
||||||
thumb_func_end sub_8081BEC
|
thumb_func_end sub_8081BEC
|
||||||
|
|
||||||
thumb_func_start sub_8081C9C
|
thumb_func_start IsTrainerInRangeSouth
|
||||||
sub_8081C9C: @ 8081C9C
|
IsTrainerInRangeSouth: @ 8081C9C
|
||||||
push {r4,r5,lr}
|
push {r4,r5,lr}
|
||||||
adds r4, r0, 0
|
adds r4, r0, 0
|
||||||
lsls r1, 16
|
lsls r1, 16
|
||||||
@@ -242,7 +242,7 @@ _08081CE6:
|
|||||||
pop {r4,r5}
|
pop {r4,r5}
|
||||||
pop {r1}
|
pop {r1}
|
||||||
bx r1
|
bx r1
|
||||||
thumb_func_end sub_8081C9C
|
thumb_func_end IsTrainerInRangeSouth
|
||||||
|
|
||||||
thumb_func_start IsTrainerInRangeNorth
|
thumb_func_start IsTrainerInRangeNorth
|
||||||
IsTrainerInRangeNorth: @ 8081CEC
|
IsTrainerInRangeNorth: @ 8081CEC
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
@@ -0,0 +1,15 @@
|
|||||||
|
.include "asm/macros.inc"
|
||||||
|
.include "constants/constants.inc"
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
gUnknown_83C6AB0:: @ 83C6AB0
|
||||||
|
.byte 0, 16, 11, 11, 2, 15
|
||||||
|
.2byte 0x125
|
||||||
|
|
||||||
|
gUnknown_83C6AB8:: @ 83C6AB8
|
||||||
|
.4byte gUnknown_841DF8B
|
||||||
|
.4byte gUnknown_841DF92
|
||||||
|
.4byte gUnknown_841DF99
|
||||||
|
.4byte gUnknown_841DFA0
|
||||||
+3
-34
@@ -1,43 +1,12 @@
|
|||||||
|
#include "constants/maps.h"
|
||||||
|
#include "constants/species.h"
|
||||||
.include "asm/macros.inc"
|
.include "asm/macros.inc"
|
||||||
.include "constants/constants.inc"
|
.include "constants/constants.inc"
|
||||||
|
|
||||||
.section .rodata
|
.section .rodata
|
||||||
.align 2
|
.align 2
|
||||||
|
|
||||||
gUnknown_83C68E0:: @ 83C68E0
|
.incbin "baserom.gba", 0x3CA770, 0xE80
|
||||||
.incbin "baserom.gba", 0x3C68E0, 0x4
|
|
||||||
|
|
||||||
gUnknown_83C68E4:: @ 83C68E4
|
|
||||||
.incbin "baserom.gba", 0x3C68E4, 0x8
|
|
||||||
|
|
||||||
gUnknown_83C68EC:: @ 83C68EC
|
|
||||||
.incbin "baserom.gba", 0x3C68EC, 0x4
|
|
||||||
|
|
||||||
.section .rodata.83C6AB0
|
|
||||||
|
|
||||||
gUnknown_83C6AB0:: @ 83C6AB0
|
|
||||||
.incbin "baserom.gba", 0x3C6AB0, 0x8
|
|
||||||
|
|
||||||
gUnknown_83C6AB8:: @ 83C6AB8
|
|
||||||
.incbin "baserom.gba", 0x3C6AB8, 0x790
|
|
||||||
|
|
||||||
gUnknown_83C7248:: @ 83C7248
|
|
||||||
.incbin "baserom.gba", 0x3C7248, 0x10
|
|
||||||
|
|
||||||
gUnknown_83C7258:: @ 83C7258
|
|
||||||
.incbin "baserom.gba", 0x3C7258, 0x3C
|
|
||||||
|
|
||||||
gUnknown_83C7294:: @ 83C7294
|
|
||||||
.incbin "baserom.gba", 0x3C7294, 0xF4
|
|
||||||
|
|
||||||
gUnknown_83C7388:: @ 83C7388
|
|
||||||
.incbin "baserom.gba", 0x3C7388, 0x2930
|
|
||||||
|
|
||||||
gWildMonHeaders:: @ 83C9CB8
|
|
||||||
.incbin "baserom.gba", 0x3C9CB8, 0xA64
|
|
||||||
|
|
||||||
gUnknown_83CA71C:: @ 83CA71C
|
|
||||||
.incbin "baserom.gba", 0x3CA71C, 0xED4
|
|
||||||
|
|
||||||
gUnknown_83CB5F0:: @ 83CB5F0
|
gUnknown_83CB5F0:: @ 83CB5F0
|
||||||
.incbin "baserom.gba", 0x3CB5F0, 0x200
|
.incbin "baserom.gba", 0x3CB5F0, 0x200
|
||||||
|
|||||||
@@ -10397,7 +10397,7 @@ EventScript_1BE06F:: @ 81BE06F
|
|||||||
applymovement VAR_LAST_TALKED, Movement_1BE08F
|
applymovement VAR_LAST_TALKED, Movement_1BE08F
|
||||||
waitmovement 0
|
waitmovement 0
|
||||||
removeobject VAR_LAST_TALKED
|
removeobject VAR_LAST_TALKED
|
||||||
special Special_RockSmashEncounter
|
special ScrSpecial_RockSmashWildEncounter
|
||||||
compare_var_to_value VAR_RESULT, 0
|
compare_var_to_value VAR_RESULT, 0
|
||||||
goto_if eq, EventScript_1BE08D
|
goto_if eq, EventScript_1BE08D
|
||||||
waitstate
|
waitstate
|
||||||
@@ -11731,7 +11731,7 @@ EventScript_81BFB5F:: @ 81BFB5F
|
|||||||
setflashradius 0
|
setflashradius 0
|
||||||
end
|
end
|
||||||
|
|
||||||
EventScript_1BFB65:: @ 81BFB65
|
EventScript_RepelWoreOff:: @ 81BFB65
|
||||||
msgbox Text_1BFB6E, 3
|
msgbox Text_1BFB6E, 3
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
.include "asm/macros.inc"
|
||||||
|
.include "constants/constants.inc"
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
gUnknown_83C68E0:: @ 83C68E0
|
||||||
|
.4byte 4
|
||||||
|
|
||||||
|
gUnknown_83C68E4:: @ 83C68E4
|
||||||
|
.byte 0, 0, 5, 30, 11, 15
|
||||||
|
.2byte 0x001
|
||||||
|
|
||||||
|
gUnknown_83C68EC:: @ 83C68EC
|
||||||
|
.byte 0, 1, 2
|
||||||
+1
-1
@@ -179,7 +179,7 @@ gSpecials:: @ 815FD60
|
|||||||
def_special sub_8113510
|
def_special sub_8113510
|
||||||
def_special sub_81130A8
|
def_special sub_81130A8
|
||||||
def_special sub_8113530
|
def_special sub_8113530
|
||||||
def_special Special_RockSmashEncounter
|
def_special ScrSpecial_RockSmashWildEncounter
|
||||||
def_special nullsub_75
|
def_special nullsub_75
|
||||||
def_special nullsub_75
|
def_special nullsub_75
|
||||||
def_special nullsub_75
|
def_special nullsub_75
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
.include "asm/macros.inc"
|
||||||
|
.include "constants/constants.inc"
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
gUnknown_83C6AC8::
|
||||||
|
.incbin "graphics/map_objects/emoticons.4bpp"
|
||||||
|
|
||||||
|
gUnknown_83C7248:: @ 83C7248
|
||||||
|
.4byte IsTrainerInRangeSouth
|
||||||
|
.4byte IsTrainerInRangeNorth
|
||||||
|
.4byte IsTrainerInRangeWest
|
||||||
|
.4byte IsTrainerInRangeEast
|
||||||
|
|
||||||
|
gUnknown_83C7258:: @ 83C7258
|
||||||
|
.4byte sub_8081F34
|
||||||
|
.4byte sub_8081F38
|
||||||
|
.4byte sub_8081F90
|
||||||
|
.4byte sub_8081FD0
|
||||||
|
.4byte sub_808202C
|
||||||
|
.4byte sub_80820BC
|
||||||
|
.4byte sub_8082100
|
||||||
|
.4byte sub_8082134
|
||||||
|
.4byte sub_8082150
|
||||||
|
.4byte sub_8082184
|
||||||
|
.4byte sub_80821DC
|
||||||
|
.4byte sub_8082250
|
||||||
|
.4byte sub_808226C
|
||||||
|
.4byte sub_80822CC
|
||||||
|
.4byte sub_808237C
|
||||||
|
|
||||||
|
gUnknown_83C7294:: @ 83C7294
|
||||||
|
.4byte sub_8082150
|
||||||
|
.4byte sub_8082184
|
||||||
|
.4byte sub_80821DC
|
||||||
|
.4byte sub_8082250
|
||||||
|
|
||||||
|
gOamData_83C72A4::
|
||||||
|
.4byte 0x40000000, 0x00000400
|
||||||
|
|
||||||
|
gSpriteImages_83C72AC::
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x000, 0x80
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x080, 0x80
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x100, 0x80
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x300, 0x80
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x380, 0x80
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x400, 0x80
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x180, 0x80
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x200, 0x80
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x280, 0x80
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x480, 0x80
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x500, 0x80
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x580, 0x80
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x600, 0x80
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x680, 0x80
|
||||||
|
.4byte gUnknown_83C6AC8 + 0x700, 0x80
|
||||||
|
|
||||||
|
gAnimCmd_83C7324::
|
||||||
|
obj_image_anim_frame 0x0000, 0x0004
|
||||||
|
obj_image_anim_frame 0x0001, 0x0004
|
||||||
|
obj_image_anim_frame 0x0002, 0x0034
|
||||||
|
obj_image_anim_end
|
||||||
|
|
||||||
|
gAnimCmd_83C7334::
|
||||||
|
obj_image_anim_frame 0x0006, 0x0004
|
||||||
|
obj_image_anim_frame 0x0007, 0x0004
|
||||||
|
obj_image_anim_frame 0x0008, 0x0034
|
||||||
|
obj_image_anim_end
|
||||||
|
|
||||||
|
gAnimCmd_83C7344::
|
||||||
|
obj_image_anim_frame 0x0003, 0x0004
|
||||||
|
obj_image_anim_frame 0x0004, 0x0004
|
||||||
|
obj_image_anim_frame 0x0005, 0x0034
|
||||||
|
obj_image_anim_end
|
||||||
|
|
||||||
|
gAnimCmd_83C7354::
|
||||||
|
obj_image_anim_frame 0x0009, 0x0004
|
||||||
|
obj_image_anim_frame 0x000a, 0x0004
|
||||||
|
obj_image_anim_frame 0x000b, 0x0034
|
||||||
|
obj_image_anim_end
|
||||||
|
|
||||||
|
gAnimCmd_83C7364::
|
||||||
|
obj_image_anim_frame 0x000c, 0x0004
|
||||||
|
obj_image_anim_frame 0x000d, 0x0004
|
||||||
|
obj_image_anim_frame 0x000e, 0x0034
|
||||||
|
obj_image_anim_end
|
||||||
|
|
||||||
|
gSpriteAnimTable_83C7374::
|
||||||
|
.4byte gAnimCmd_83C7324
|
||||||
|
.4byte gAnimCmd_83C7334
|
||||||
|
.4byte gAnimCmd_83C7344
|
||||||
|
.4byte gAnimCmd_83C7354
|
||||||
|
.4byte gAnimCmd_83C7364
|
||||||
|
|
||||||
|
gUnknown_83C7388:: @ 83C7388
|
||||||
|
spr_template 65535, 65535, gOamData_83C72A4, gSpriteAnimTable_83C7374, gSpriteImages_83C72AC, gDummySpriteAffineAnimTable, objc_exclamation_mark_probably
|
||||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 544 B |
@@ -521,3 +521,6 @@ graphics/pokemon/heracross/unk_icon.4bpp: %.4bpp: %.png
|
|||||||
|
|
||||||
graphics/map_objects/151.4bpp: %.4bpp: %.png
|
graphics/map_objects/151.4bpp: %.4bpp: %.png
|
||||||
$(GFX) $< $@ -mwidth 8 -mheight 4
|
$(GFX) $< $@ -mwidth 8 -mheight 4
|
||||||
|
|
||||||
|
graphics/map_objects/emoticons.4bpp: %.4bpp: %.png
|
||||||
|
$(GFX) $< $@ -mwidth 2 -mheight 2
|
||||||
|
|||||||
@@ -1186,4 +1186,6 @@ extern const u8 Text_1BCA95[];
|
|||||||
extern const u8 Text_1BCACB[];
|
extern const u8 Text_1BCACB[];
|
||||||
extern const u8 Text_1BCAF2[];
|
extern const u8 Text_1BCAF2[];
|
||||||
|
|
||||||
|
extern const u8 EventScript_RepelWoreOff[];
|
||||||
|
|
||||||
#endif //GUARD_EVENT_SCRIPTS_H
|
#endif //GUARD_EVENT_SCRIPTS_H
|
||||||
|
|||||||
@@ -28,5 +28,7 @@ struct MapConnection * GetMapConnectionAtPos(s16 x, s16 y);
|
|||||||
void sub_8059948(u8 a0, u8 a1);
|
void sub_8059948(u8 a0, u8 a1);
|
||||||
|
|
||||||
void save_serialize_map(void);
|
void save_serialize_map(void);
|
||||||
|
u32 sub_8058F1C(u32 original, u8 bit);
|
||||||
|
u32 sub_8058F48(s16 x, s16 y, u8 z);
|
||||||
|
|
||||||
#endif //GUARD_FIELDMAP_H
|
#endif //GUARD_FIELDMAP_H
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ struct WildPokemonHeader
|
|||||||
extern const struct WildPokemonHeader gWildMonHeaders[];
|
extern const struct WildPokemonHeader gWildMonHeaders[];
|
||||||
|
|
||||||
void DisableWildEncounters(bool8 disabled);
|
void DisableWildEncounters(bool8 disabled);
|
||||||
bool8 StandardWildEncounter(u16 currMetaTileBehavior, u16 previousMetaTileBehavior);
|
bool8 StandardWildEncounter(u32 currMetaTileBehavior, u16 previousMetaTileBehavior);
|
||||||
void ScrSpecial_RockSmashWildEncounter(void);
|
void ScrSpecial_RockSmashWildEncounter(void);
|
||||||
bool8 SweetScentWildEncounter(void);
|
bool8 SweetScentWildEncounter(void);
|
||||||
bool8 DoesCurrentMapHaveFishingMons(void);
|
bool8 DoesCurrentMapHaveFishingMons(void);
|
||||||
@@ -42,9 +42,10 @@ void FishingWildEncounter(u8 rod);
|
|||||||
u16 GetLocalWildMon(bool8 *isWaterMon);
|
u16 GetLocalWildMon(bool8 *isWaterMon);
|
||||||
u16 GetLocalWaterMon(void);
|
u16 GetLocalWaterMon(void);
|
||||||
bool8 UpdateRepelCounter(void);
|
bool8 UpdateRepelCounter(void);
|
||||||
void sub_8082740(u8);
|
void DisableWildEncounters(bool8 state);
|
||||||
u8 GetUnownLetterByPersonalityLoByte(u32 personality);
|
u8 GetUnownLetterByPersonalityLoByte(u32 personality);
|
||||||
bool8 SweetScentWildEncounter(void);
|
bool8 SweetScentWildEncounter(void);
|
||||||
void sub_8083214(u16 randVal);
|
void SeedWildEncounterRng(u16 randVal);
|
||||||
|
void ResetEncounterRateModifiers(void);
|
||||||
|
|
||||||
#endif // GUARD_WILD_ENCOUNTER_H
|
#endif // GUARD_WILD_ENCOUNTER_H
|
||||||
|
|||||||
+9
-3
@@ -1,9 +1,15 @@
|
|||||||
# JSON files are run through jsonproc, which is a tool that converts JSON data to an output file
|
# JSON files are run through jsonproc, which is a tool that converts JSON data to an output file
|
||||||
# based on an Inja template. https://github.com/pantor/inja
|
# based on an Inja template. https://github.com/pantor/inja
|
||||||
|
|
||||||
AUTO_GEN_TARGETS += src/data/items.h
|
AUTO_GEN_TARGETS += $(DATA_C_SUBDIR)/items.h
|
||||||
|
|
||||||
src/data/items.h: src/data/items.json src/data/items.json.txt
|
$(DATA_C_SUBDIR)/items.h: $(DATA_C_SUBDIR)/items.json $(DATA_C_SUBDIR)/items.json.txt
|
||||||
$(JSONPROC) $^ $@
|
$(JSONPROC) $^ $@
|
||||||
|
|
||||||
$(C_BUILDDIR)/item.o: c_dep += src/data/items.h
|
$(C_BUILDDIR)/item.o: c_dep += $(DATA_C_SUBDIR)/items.h
|
||||||
|
|
||||||
|
AUTO_GEN_TARGETS += $(DATA_C_SUBDIR)/wild_encounters.h
|
||||||
|
$(DATA_C_SUBDIR)/wild_encounters.h: $(DATA_C_SUBDIR)/wild_encounters.json $(DATA_C_SUBDIR)/wild_encounters.json.txt
|
||||||
|
$(JSONPROC) $^ $@
|
||||||
|
|
||||||
|
$(C_BUILDDIR)/wild_encounter.o: c_dep += $(DATA_C_SUBDIR)/wild_encounters.h
|
||||||
|
|||||||
+6
-3
@@ -125,7 +125,7 @@ SECTIONS {
|
|||||||
src/battle_setup.o(.text);
|
src/battle_setup.o(.text);
|
||||||
asm/cable_club.o(.text);
|
asm/cable_club.o(.text);
|
||||||
asm/trainer_see.o(.text);
|
asm/trainer_see.o(.text);
|
||||||
asm/wild_encounter.o(.text);
|
src/wild_encounter.o(.text);
|
||||||
asm/field_effect.o(.text);
|
asm/field_effect.o(.text);
|
||||||
src/scanline_effect.o(.text);
|
src/scanline_effect.o(.text);
|
||||||
asm/option_menu.o(.text);
|
asm/option_menu.o(.text);
|
||||||
@@ -426,9 +426,12 @@ SECTIONS {
|
|||||||
data/battle_anim_status_effects.o(.rodata);
|
data/battle_anim_status_effects.o(.rodata);
|
||||||
src/title_screen.o(.rodata);
|
src/title_screen.o(.rodata);
|
||||||
data/field_weather.o(.rodata);
|
data/field_weather.o(.rodata);
|
||||||
data/data_835B488.o(.rodata);
|
data/field_screen_effect.o(.rodata);
|
||||||
src/battle_setup.o(.rodata);
|
src/battle_setup.o(.rodata);
|
||||||
data/data_835B488.o(.rodata.83C6AB0);
|
data/cable_club.o(.rodata);
|
||||||
|
data/trainer_see.o(.rodata);
|
||||||
|
src/wild_encounter.o(.rodata);
|
||||||
|
data/data_835B488.o(.rodata);
|
||||||
src/pokemon_icon.o(.rodata);
|
src/pokemon_icon.o(.rodata);
|
||||||
data/data_835B488.o(.rodata.83D4100);
|
data/data_835B488.o(.rodata.83D4100);
|
||||||
src/item_menu_icons.o(.rodata);
|
src/item_menu_icons.o(.rodata);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,90 @@
|
|||||||
|
{{ doNotModifyHeader }}
|
||||||
|
|
||||||
|
## for wild_encounter_group in wild_encounter_groups
|
||||||
|
{% if wild_encounter_group.for_maps %}
|
||||||
|
## for wild_encounter_field in wild_encounter_group.fields
|
||||||
|
{% if not existsIn(wild_encounter_field, "groups") %}
|
||||||
|
## for encounter_rate in wild_encounter_field.encounter_rates
|
||||||
|
{% if loop.index == 0 %}
|
||||||
|
#define ENCOUNTER_CHANCE_{{ upper(wild_encounter_field.type) }}_SLOT_{{ loop.index }} {{ encounter_rate }} {% else %}#define ENCOUNTER_CHANCE_{{ upper(wild_encounter_field.type) }}_SLOT_{{ loop.index }} ENCOUNTER_CHANCE_{{ upper(wild_encounter_field.type) }}_SLOT_{{ subtract(loop.index, 1) }} + {{ encounter_rate }}{% endif %} {{ setVarInt(wild_encounter_field.type, loop.index) }}
|
||||||
|
## endfor
|
||||||
|
#define ENCOUNTER_CHANCE_{{ upper(wild_encounter_field.type) }}_TOTAL (ENCOUNTER_CHANCE_{{ upper(wild_encounter_field.type) }}_SLOT_{{ getVar(wild_encounter_field.type) }})
|
||||||
|
{% else %}
|
||||||
|
## for field_subgroup_key, field_subgroup_subarray in wild_encounter_field.groups
|
||||||
|
## for field_subgroup_index in field_subgroup_subarray
|
||||||
|
{% if loop.index == 0 %}
|
||||||
|
#define ENCOUNTER_CHANCE_{{ upper(wild_encounter_field.type) }}_{{ upper(field_subgroup_key) }}_SLOT_{{ field_subgroup_index }} {{ at(wild_encounter_field.encounter_rates, field_subgroup_index) }} {% else %}#define ENCOUNTER_CHANCE_{{ upper(wild_encounter_field.type) }}_{{ upper(field_subgroup_key) }}_SLOT_{{ field_subgroup_index }} ENCOUNTER_CHANCE_{{ upper(wild_encounter_field.type) }}_{{ upper(field_subgroup_key) }}_SLOT_{{ getVar("previous_slot") }} + {{ at(wild_encounter_field.encounter_rates, field_subgroup_index) }}{% endif %}{{ setVarInt(concat(wild_encounter_field.type, field_subgroup_key), field_subgroup_index) }}{{ setVarInt("previous_slot", field_subgroup_index) }}
|
||||||
|
## endfor
|
||||||
|
#define ENCOUNTER_CHANCE_{{ upper(wild_encounter_field.type) }}_{{ upper(field_subgroup_key) }}_TOTAL (ENCOUNTER_CHANCE_{{ upper(wild_encounter_field.type) }}_{{ upper(field_subgroup_key) }}_SLOT_{{ getVar(concat(wild_encounter_field.type, field_subgroup_key)) }})
|
||||||
|
## endfor
|
||||||
|
{% endif %}
|
||||||
|
## endfor
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## for encounter in wild_encounter_group.encounters
|
||||||
|
{% if existsIn(encounter, "land_mons") %}
|
||||||
|
const struct WildPokemon {{ encounter.base_label }}_LandMons[] =
|
||||||
|
{
|
||||||
|
## for wild_mon in encounter.land_mons.mons
|
||||||
|
{ {{ wild_mon.min_level }}, {{ wild_mon.max_level }}, {{ wild_mon.species }} },
|
||||||
|
## endfor
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct WildPokemonInfo {{ encounter.base_label }}_LandMonsInfo = { {{encounter.land_mons.encounter_rate}}, {{ encounter.base_label }}_LandMons };
|
||||||
|
{% endif %}
|
||||||
|
{% if existsIn(encounter, "water_mons") %}
|
||||||
|
const struct WildPokemon {{ encounter.base_label }}_WaterMons[] =
|
||||||
|
{
|
||||||
|
## for wild_mon in encounter.water_mons.mons
|
||||||
|
{ {{ wild_mon.min_level }}, {{ wild_mon.max_level }}, {{ wild_mon.species }} },
|
||||||
|
## endfor
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct WildPokemonInfo {{ encounter.base_label }}_WaterMonsInfo = { {{encounter.water_mons.encounter_rate}}, {{ encounter.base_label }}_WaterMons };
|
||||||
|
{% endif %}
|
||||||
|
{% if existsIn(encounter, "rock_smash_mons") %}
|
||||||
|
const struct WildPokemon {{ encounter.base_label }}_RockSmashMons[] =
|
||||||
|
{
|
||||||
|
## for wild_mon in encounter.rock_smash_mons.mons
|
||||||
|
{ {{ wild_mon.min_level }}, {{ wild_mon.max_level }}, {{ wild_mon.species }} },
|
||||||
|
## endfor
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct WildPokemonInfo {{ encounter.base_label }}_RockSmashMonsInfo = { {{encounter.rock_smash_mons.encounter_rate}}, {{ encounter.base_label }}_RockSmashMons };
|
||||||
|
{% endif %}
|
||||||
|
{% if existsIn(encounter, "fishing_mons") %}
|
||||||
|
const struct WildPokemon {{ encounter.base_label }}_FishingMons[] =
|
||||||
|
{
|
||||||
|
## for wild_mon in encounter.fishing_mons.mons
|
||||||
|
{ {{ wild_mon.min_level }}, {{ wild_mon.max_level }}, {{ wild_mon.species }} },
|
||||||
|
## endfor
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct WildPokemonInfo {{ encounter.base_label }}_FishingMonsInfo = { {{encounter.fishing_mons.encounter_rate}}, {{ encounter.base_label }}_FishingMons };
|
||||||
|
{% endif %}
|
||||||
|
## endfor
|
||||||
|
|
||||||
|
const struct WildPokemonHeader {{ wild_encounter_group.label }}[] =
|
||||||
|
{
|
||||||
|
## for encounter in wild_encounter_group.encounters
|
||||||
|
{
|
||||||
|
.mapGroup = {% if wild_encounter_group.for_maps %}MAP_GROUP({{ removePrefix(encounter.map, "MAP_") }}){% else %}0{% endif %},
|
||||||
|
.mapNum = {% if wild_encounter_group.for_maps %}MAP_NUM({{ removePrefix(encounter.map, "MAP_") }}){% else %}{{ loop.index1 }}{% endif %},
|
||||||
|
.landMonsInfo = {% if existsIn(encounter, "land_mons") %}&{{ encounter.base_label }}_LandMonsInfo{% else %}NULL{% endif %},
|
||||||
|
.waterMonsInfo = {% if existsIn(encounter, "water_mons") %}&{{ encounter.base_label }}_WaterMonsInfo{% else %}NULL{% endif %},
|
||||||
|
.rockSmashMonsInfo = {% if existsIn(encounter, "rock_smash_mons") %}&{{ encounter.base_label }}_RockSmashMonsInfo{% else %}NULL{% endif %},
|
||||||
|
.fishingMonsInfo = {% if existsIn(encounter, "fishing_mons") %}&{{ encounter.base_label }}_FishingMonsInfo{% else %}NULL{% endif %},
|
||||||
|
},
|
||||||
|
## endfor
|
||||||
|
{
|
||||||
|
.mapGroup = MAP_GROUP(UNDEFINED),
|
||||||
|
.mapNum = MAP_NUM(UNDEFINED),
|
||||||
|
.landMonsInfo = NULL,
|
||||||
|
.waterMonsInfo = NULL,
|
||||||
|
.rockSmashMonsInfo = NULL,
|
||||||
|
.fishingMonsInfo = NULL,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
## endfor
|
||||||
+1
-1
@@ -102,7 +102,7 @@ void ResetMenuAndMonGlobals(void)
|
|||||||
ResetTMCaseCursorPos();
|
ResetTMCaseCursorPos();
|
||||||
BerryPouch_CursorResetToTop();
|
BerryPouch_CursorResetToTop();
|
||||||
sub_811089C();
|
sub_811089C();
|
||||||
sub_8083214(Random());
|
SeedWildEncounterRng(Random());
|
||||||
ResetSpecialVars();
|
ResetSpecialVars();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -870,7 +870,7 @@ static void sub_8110F90(u8 unused)
|
|||||||
gSaveBlock1Ptr->location.warpId = -1;
|
gSaveBlock1Ptr->location.warpId = -1;
|
||||||
gUnknown_203ADF8 = 0;
|
gUnknown_203ADF8 = 0;
|
||||||
gDisableMapMusicChangeOnMapLoad = 1;
|
gDisableMapMusicChangeOnMapLoad = 1;
|
||||||
sub_8082740(1);
|
DisableWildEncounters(TRUE);
|
||||||
sub_8111368();
|
sub_8111368();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1600,7 +1600,7 @@ static void sub_81120AC(u8 taskId)
|
|||||||
ScriptContext2_Disable();
|
ScriptContext2_Disable();
|
||||||
gTextFlags.autoScroll = FALSE;
|
gTextFlags.autoScroll = FALSE;
|
||||||
gUnknown_2036E28 = 0;
|
gUnknown_2036E28 = 0;
|
||||||
sub_8082740(0);
|
DisableWildEncounters(FALSE);
|
||||||
gHelpSystemEnabled = TRUE;
|
gHelpSystemEnabled = TRUE;
|
||||||
DestroyTask(taskId);
|
DestroyTask(taskId);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -0,0 +1,789 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "random.h"
|
||||||
|
#include "wild_encounter.h"
|
||||||
|
#include "event_data.h"
|
||||||
|
#include "fieldmap.h"
|
||||||
|
#include "roamer.h"
|
||||||
|
#include "field_player_avatar.h"
|
||||||
|
#include "battle_setup.h"
|
||||||
|
#include "overworld.h"
|
||||||
|
#include "metatile_behavior.h"
|
||||||
|
#include "event_scripts.h"
|
||||||
|
#include "script.h"
|
||||||
|
#include "link.h"
|
||||||
|
#include "quest_log.h"
|
||||||
|
#include "constants/species.h"
|
||||||
|
#include "constants/maps.h"
|
||||||
|
#include "constants/vars.h"
|
||||||
|
#include "constants/abilities.h"
|
||||||
|
#include "constants/items.h"
|
||||||
|
|
||||||
|
struct WildEncounterData
|
||||||
|
{
|
||||||
|
u32 rngState;
|
||||||
|
u16 prevMetatileBehavior;
|
||||||
|
u16 encounterRateBuff;
|
||||||
|
u8 stepsSinceLastEncounter;
|
||||||
|
u8 abilityEffect;
|
||||||
|
u16 leadMonHeldItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
static EWRAM_DATA struct WildEncounterData sWildEncounterData = {};
|
||||||
|
static EWRAM_DATA bool8 sWildEncountersDisabled = FALSE;
|
||||||
|
|
||||||
|
static bool8 UnlockedTanobyOrAreNotInTanoby(void);
|
||||||
|
static u32 GenerateUnownPersonalityByLetter(u8 letter);
|
||||||
|
static bool8 IsWildLevelAllowedByRepel(u8 level);
|
||||||
|
static void ApplyFluteEncounterRateMod(u32 *rate);
|
||||||
|
static u8 GetFluteEncounterRateModType(void);
|
||||||
|
static void ApplyCleanseTagEncounterRateMod(u32 *rate);
|
||||||
|
static bool8 IsLeadMonHoldingCleanseTag(void);
|
||||||
|
static u16 WildEncounterRandom(void);
|
||||||
|
static void AddToWildEncounterRateBuff(u8 encouterRate);
|
||||||
|
|
||||||
|
#include "data/wild_encounters.h"
|
||||||
|
|
||||||
|
static const u8 sUnownLetterSlots[][12] = {
|
||||||
|
// A A A A A A A A A A A ?
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27},
|
||||||
|
// C C C D D D H H H U U O
|
||||||
|
{ 2, 2, 2, 3, 3, 3, 7, 7, 7, 20, 20, 14},
|
||||||
|
// N N N N S S S S I I E E
|
||||||
|
{13, 13, 13, 13, 18, 18, 18, 18, 8, 8, 4, 4},
|
||||||
|
// P P L L J J R R R Q Q Q
|
||||||
|
{15, 15, 11, 11, 9, 9, 17, 17, 17, 16, 16, 16},
|
||||||
|
// Y Y T T G G G F F F K K
|
||||||
|
{24, 24, 19, 19, 6, 6, 6, 5, 5, 5, 10, 10},
|
||||||
|
// V V V W W W X X M M B B
|
||||||
|
{21, 21, 21, 22, 22, 22, 23, 23, 12, 12, 1, 1},
|
||||||
|
// Z Z Z Z Z Z Z Z Z Z Z !
|
||||||
|
{25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26},
|
||||||
|
};
|
||||||
|
|
||||||
|
void DisableWildEncounters(bool8 state)
|
||||||
|
{
|
||||||
|
sWildEncountersDisabled = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 ChooseWildMonIndex_Land(void)
|
||||||
|
{
|
||||||
|
u8 rand = Random() % ENCOUNTER_CHANCE_LAND_MONS_TOTAL;
|
||||||
|
|
||||||
|
if (rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_0)
|
||||||
|
return 0;
|
||||||
|
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_0 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_1)
|
||||||
|
return 1;
|
||||||
|
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_1 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_2)
|
||||||
|
return 2;
|
||||||
|
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_2 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_3)
|
||||||
|
return 3;
|
||||||
|
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_3 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_4)
|
||||||
|
return 4;
|
||||||
|
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_4 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_5)
|
||||||
|
return 5;
|
||||||
|
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_5 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_6)
|
||||||
|
return 6;
|
||||||
|
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_6 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_7)
|
||||||
|
return 7;
|
||||||
|
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_7 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_8)
|
||||||
|
return 8;
|
||||||
|
else if (rand >= ENCOUNTER_CHANCE_LAND_MONS_SLOT_8 && rand < ENCOUNTER_CHANCE_LAND_MONS_SLOT_9)
|
||||||
|
return 9;
|
||||||
|
else if (rand == ENCOUNTER_CHANCE_LAND_MONS_SLOT_9)
|
||||||
|
return 10;
|
||||||
|
else
|
||||||
|
return 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 ChooseWildMonIndex_WaterRock(void)
|
||||||
|
{
|
||||||
|
u8 rand = Random() % ENCOUNTER_CHANCE_WATER_MONS_TOTAL;
|
||||||
|
|
||||||
|
if (rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_0)
|
||||||
|
return 0;
|
||||||
|
else if (rand >= ENCOUNTER_CHANCE_WATER_MONS_SLOT_0 && rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_1)
|
||||||
|
return 1;
|
||||||
|
else if (rand >= ENCOUNTER_CHANCE_WATER_MONS_SLOT_1 && rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_2)
|
||||||
|
return 2;
|
||||||
|
else if (rand >= ENCOUNTER_CHANCE_WATER_MONS_SLOT_2 && rand < ENCOUNTER_CHANCE_WATER_MONS_SLOT_3)
|
||||||
|
return 3;
|
||||||
|
else
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
OLD_ROD,
|
||||||
|
GOOD_ROD,
|
||||||
|
SUPER_ROD
|
||||||
|
};
|
||||||
|
|
||||||
|
static u8 ChooseWildMonIndex_Fishing(u8 rod)
|
||||||
|
{
|
||||||
|
u8 wildMonIndex = 0;
|
||||||
|
u8 rand = Random() % max(max(ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_TOTAL, ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_TOTAL),
|
||||||
|
ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_TOTAL);
|
||||||
|
|
||||||
|
switch (rod)
|
||||||
|
{
|
||||||
|
case OLD_ROD:
|
||||||
|
if (rand < ENCOUNTER_CHANCE_FISHING_MONS_OLD_ROD_SLOT_0)
|
||||||
|
wildMonIndex = 0;
|
||||||
|
else
|
||||||
|
wildMonIndex = 1;
|
||||||
|
break;
|
||||||
|
case GOOD_ROD:
|
||||||
|
if (rand < ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_2)
|
||||||
|
wildMonIndex = 2;
|
||||||
|
if (rand >= ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_2 && rand < ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_3)
|
||||||
|
wildMonIndex = 3;
|
||||||
|
if (rand >= ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_3 && rand < ENCOUNTER_CHANCE_FISHING_MONS_GOOD_ROD_SLOT_4)
|
||||||
|
wildMonIndex = 4;
|
||||||
|
break;
|
||||||
|
case SUPER_ROD:
|
||||||
|
if (rand < ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_5)
|
||||||
|
wildMonIndex = 5;
|
||||||
|
if (rand >= ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_5 && rand < ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_6)
|
||||||
|
wildMonIndex = 6;
|
||||||
|
if (rand >= ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_6 && rand < ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_7)
|
||||||
|
wildMonIndex = 7;
|
||||||
|
if (rand >= ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_7 && rand < ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_8)
|
||||||
|
wildMonIndex = 8;
|
||||||
|
if (rand == ENCOUNTER_CHANCE_FISHING_MONS_SUPER_ROD_SLOT_8)
|
||||||
|
wildMonIndex = 9;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return wildMonIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 ChooseWildMonLevel(const struct WildPokemon * info)
|
||||||
|
{
|
||||||
|
u8 lo;
|
||||||
|
u8 hi;
|
||||||
|
u8 mod;
|
||||||
|
u8 res;
|
||||||
|
if (info->maxLevel >= info->minLevel)
|
||||||
|
{
|
||||||
|
lo = info->minLevel;
|
||||||
|
hi = info->maxLevel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lo = info->maxLevel;
|
||||||
|
hi = info->minLevel;
|
||||||
|
}
|
||||||
|
mod = hi - lo + 1;
|
||||||
|
res = Random() % mod;
|
||||||
|
return lo + res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u16 GetCurrentMapWildMonHeaderId(void)
|
||||||
|
{
|
||||||
|
u16 i;
|
||||||
|
|
||||||
|
for (i = 0; ; i++)
|
||||||
|
{
|
||||||
|
const struct WildPokemonHeader * wildHeader = &gWildMonHeaders[i];
|
||||||
|
if (wildHeader->mapGroup == 0xFF)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (gWildMonHeaders[i].mapGroup == gSaveBlock1Ptr->location.mapGroup &&
|
||||||
|
gWildMonHeaders[i].mapNum == gSaveBlock1Ptr->location.mapNum)
|
||||||
|
{
|
||||||
|
if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(SIX_ISLAND_ALTERING_CAVE) &&
|
||||||
|
gSaveBlock1Ptr->location.mapNum == MAP_NUM(SIX_ISLAND_ALTERING_CAVE))
|
||||||
|
{
|
||||||
|
u16 alteringCaveId = VarGet(VAR_ALTERING_CAVE_WILD_SET);
|
||||||
|
if (alteringCaveId > 8)
|
||||||
|
alteringCaveId = 0;
|
||||||
|
|
||||||
|
i += alteringCaveId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!UnlockedTanobyOrAreNotInTanoby())
|
||||||
|
break;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool8 UnlockedTanobyOrAreNotInTanoby(void)
|
||||||
|
{
|
||||||
|
if (FlagGet(FLAG_SYS_UNLOCKED_TANOBY_RUINS))
|
||||||
|
return TRUE;
|
||||||
|
if (gSaveBlock1Ptr->location.mapGroup != MAP_GROUP(SEVEN_ISLAND_TANOBY_RUINS_DILFORD_CHAMBER))
|
||||||
|
return TRUE;
|
||||||
|
if (!(gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_MONEAN_CHAMBER)
|
||||||
|
|| gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_LIPTOO_CHAMBER)
|
||||||
|
|| gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_WEEPTH_CHAMBER)
|
||||||
|
|| gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_DILFORD_CHAMBER)
|
||||||
|
|| gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_SCUFIB_CHAMBER)
|
||||||
|
|| gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_RIXY_CHAMBER)
|
||||||
|
|| gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_VIAPOIS_CHAMBER)
|
||||||
|
))
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenerateWildMon(u16 species, u8 level, u8 slot)
|
||||||
|
{
|
||||||
|
u32 personality;
|
||||||
|
s8 chamber;
|
||||||
|
ZeroEnemyPartyMons();
|
||||||
|
if (species != SPECIES_UNOWN)
|
||||||
|
{
|
||||||
|
CreateMonWithNature(&gEnemyParty[0], species, level, 32, Random() % 25);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chamber = gSaveBlock1Ptr->location.mapNum - MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_MONEAN_CHAMBER);
|
||||||
|
personality = GenerateUnownPersonalityByLetter(sUnownLetterSlots[chamber][slot]);
|
||||||
|
CreateMon(&gEnemyParty[0], species, level, 32, TRUE, personality, FALSE, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 GenerateUnownPersonalityByLetter(u8 letter)
|
||||||
|
{
|
||||||
|
u32 personality;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
personality = (Random() << 16) | Random();
|
||||||
|
} while (GetUnownLetterByPersonalityLoByte(personality) != letter);
|
||||||
|
return personality;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 GetUnownLetterByPersonalityLoByte(u32 personality)
|
||||||
|
{
|
||||||
|
return (((personality & 0x3000000) >> 18) | ((personality & 0x30000) >> 12) | ((personality & 0x300) >> 6) | (personality & 0x3)) % 0x1C;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
WILD_AREA_LAND,
|
||||||
|
WILD_AREA_WATER,
|
||||||
|
WILD_AREA_ROCKS,
|
||||||
|
WILD_AREA_FISHING,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define WILD_CHECK_REPEL 0x1
|
||||||
|
#define WILD_CHECK_KEEN_EYE 0x2
|
||||||
|
|
||||||
|
static bool8 TryGenerateWildMon(const struct WildPokemonInfo * info, u8 area, u8 flags)
|
||||||
|
{
|
||||||
|
u8 slot = 0;
|
||||||
|
u8 level;
|
||||||
|
switch (area)
|
||||||
|
{
|
||||||
|
case WILD_AREA_LAND:
|
||||||
|
slot = ChooseWildMonIndex_Land();
|
||||||
|
break;
|
||||||
|
case WILD_AREA_WATER:
|
||||||
|
slot = ChooseWildMonIndex_WaterRock();
|
||||||
|
break;
|
||||||
|
case WILD_AREA_ROCKS:
|
||||||
|
slot = ChooseWildMonIndex_WaterRock();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
level = ChooseWildMonLevel(&info->wildPokemon[slot]);
|
||||||
|
if (flags == WILD_CHECK_REPEL && !IsWildLevelAllowedByRepel(level))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
GenerateWildMon(info->wildPokemon[slot].species, level, slot);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u16 GenerateFishingEncounter(const struct WildPokemonInfo * info, u8 rod)
|
||||||
|
{
|
||||||
|
u8 slot = ChooseWildMonIndex_Fishing(rod);
|
||||||
|
u8 level = ChooseWildMonLevel(&info->wildPokemon[slot]);
|
||||||
|
GenerateWildMon(info->wildPokemon[slot].species, level, slot);
|
||||||
|
return info->wildPokemon[slot].species;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool8 DoWildEncounterRateDiceRoll(u16 a0)
|
||||||
|
{
|
||||||
|
if (WildEncounterRandom() % 1600 < a0)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool8 DoWildEncounterRateTest(u32 encounterRate, bool8 ignoreAbility)
|
||||||
|
{
|
||||||
|
encounterRate *= 16;
|
||||||
|
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
|
||||||
|
encounterRate = encounterRate * 80 / 100;
|
||||||
|
encounterRate += sWildEncounterData.encounterRateBuff * 16 / 200;
|
||||||
|
ApplyFluteEncounterRateMod(&encounterRate);
|
||||||
|
ApplyCleanseTagEncounterRateMod(&encounterRate);
|
||||||
|
if (!ignoreAbility)
|
||||||
|
{
|
||||||
|
switch (sWildEncounterData.abilityEffect)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
encounterRate /= 2;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
encounterRate *= 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (encounterRate > 1600)
|
||||||
|
encounterRate = 1600;
|
||||||
|
return DoWildEncounterRateDiceRoll(encounterRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 GetAbilityEncounterRateModType(void)
|
||||||
|
{
|
||||||
|
sWildEncounterData.abilityEffect = 0;
|
||||||
|
if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG))
|
||||||
|
{
|
||||||
|
u8 ability = GetMonAbility(&gPlayerParty[0]);
|
||||||
|
if (ability == ABILITY_STENCH)
|
||||||
|
sWildEncounterData.abilityEffect = 1;
|
||||||
|
else if (ability == ABILITY_ILLUMINATE)
|
||||||
|
sWildEncounterData.abilityEffect = 2;
|
||||||
|
}
|
||||||
|
return sWildEncounterData.abilityEffect;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool8 DoGlobalWildEncounterDiceRoll(void)
|
||||||
|
{
|
||||||
|
if ((Random() % 100) >= 60)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool8 StandardWildEncounter(u32 currMetatileBehavior, u16 previousMetatileBehavior)
|
||||||
|
{
|
||||||
|
u16 headerId;
|
||||||
|
struct Roamer * roamer;
|
||||||
|
|
||||||
|
if (sWildEncountersDisabled == TRUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
headerId = GetCurrentMapWildMonHeaderId();
|
||||||
|
if (headerId != 0xFFFF)
|
||||||
|
{
|
||||||
|
if (sub_8058F1C(currMetatileBehavior, 4) == TRUE)
|
||||||
|
{
|
||||||
|
if (gWildMonHeaders[headerId].landMonsInfo == NULL)
|
||||||
|
return FALSE;
|
||||||
|
else if (previousMetatileBehavior != sub_8058F1C(currMetatileBehavior, 0) && !DoGlobalWildEncounterDiceRoll())
|
||||||
|
return FALSE;
|
||||||
|
if (DoWildEncounterRateTest(gWildMonHeaders[headerId].landMonsInfo->encounterRate, FALSE) != TRUE)
|
||||||
|
{
|
||||||
|
AddToWildEncounterRateBuff(gWildMonHeaders[headerId].landMonsInfo->encounterRate);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (TryStartRoamerEncounter() == TRUE)
|
||||||
|
{
|
||||||
|
roamer = &gSaveBlock1Ptr->roamer;
|
||||||
|
if (!IsWildLevelAllowedByRepel(roamer->level))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BattleSetup_StartRoamerBattle();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
// try a regular wild land encounter
|
||||||
|
if (TryGenerateWildMon(gWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_REPEL) == TRUE)
|
||||||
|
{
|
||||||
|
BattleSetup_StartWildBattle();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddToWildEncounterRateBuff(gWildMonHeaders[headerId].landMonsInfo->encounterRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (sub_8058F1C(currMetatileBehavior, 4) == 2
|
||||||
|
|| (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING) && MetatileBehavior_IsBridge(sub_8058F1C(currMetatileBehavior, 0)) == TRUE))
|
||||||
|
{
|
||||||
|
if (gWildMonHeaders[headerId].waterMonsInfo == NULL)
|
||||||
|
return FALSE;
|
||||||
|
else if (previousMetatileBehavior != sub_8058F1C(currMetatileBehavior, 0) && !DoGlobalWildEncounterDiceRoll())
|
||||||
|
return FALSE;
|
||||||
|
else if (DoWildEncounterRateTest(gWildMonHeaders[headerId].waterMonsInfo->encounterRate, FALSE) != TRUE)
|
||||||
|
{
|
||||||
|
AddToWildEncounterRateBuff(gWildMonHeaders[headerId].waterMonsInfo->encounterRate);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryStartRoamerEncounter() == TRUE)
|
||||||
|
{
|
||||||
|
roamer = &gSaveBlock1Ptr->roamer;
|
||||||
|
if (!IsWildLevelAllowedByRepel(roamer->level))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BattleSetup_StartRoamerBattle();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else // try a regular surfing encounter
|
||||||
|
{
|
||||||
|
if (TryGenerateWildMon(gWildMonHeaders[headerId].waterMonsInfo, WILD_AREA_WATER, WILD_CHECK_REPEL) == TRUE)
|
||||||
|
{
|
||||||
|
BattleSetup_StartWildBattle();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddToWildEncounterRateBuff(gWildMonHeaders[headerId].waterMonsInfo->encounterRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrSpecial_RockSmashWildEncounter(void)
|
||||||
|
{
|
||||||
|
u16 headerIdx = GetCurrentMapWildMonHeaderId();
|
||||||
|
if (headerIdx == 0xFFFF)
|
||||||
|
gSpecialVar_Result = FALSE;
|
||||||
|
else if (gWildMonHeaders[headerIdx].rockSmashMonsInfo == NULL)
|
||||||
|
gSpecialVar_Result = FALSE;
|
||||||
|
else if (DoWildEncounterRateTest(gWildMonHeaders[headerIdx].rockSmashMonsInfo->encounterRate, TRUE) != TRUE)
|
||||||
|
gSpecialVar_Result = FALSE;
|
||||||
|
else if (TryGenerateWildMon(gWildMonHeaders[headerIdx].rockSmashMonsInfo, WILD_AREA_ROCKS, WILD_CHECK_REPEL) == TRUE)
|
||||||
|
{
|
||||||
|
BattleSetup_StartWildBattle();
|
||||||
|
gSpecialVar_Result = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gSpecialVar_Result = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool8 SweetScentWildEncounter(void)
|
||||||
|
{
|
||||||
|
s16 x, y;
|
||||||
|
u16 headerId;
|
||||||
|
|
||||||
|
PlayerGetDestCoords(&x, &y);
|
||||||
|
headerId = GetCurrentMapWildMonHeaderId();
|
||||||
|
if (headerId != 0xFFFF)
|
||||||
|
{
|
||||||
|
if (sub_8058F48(x, y, 4) == 1)
|
||||||
|
{
|
||||||
|
if (TryStartRoamerEncounter() == TRUE)
|
||||||
|
{
|
||||||
|
BattleSetup_StartRoamerBattle();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gWildMonHeaders[headerId].landMonsInfo == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
TryGenerateWildMon(gWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, 0);
|
||||||
|
|
||||||
|
BattleSetup_StartWildBattle();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (sub_8058F48(x, y, 4) == 2)
|
||||||
|
{
|
||||||
|
if (TryStartRoamerEncounter() == TRUE)
|
||||||
|
{
|
||||||
|
BattleSetup_StartRoamerBattle();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gWildMonHeaders[headerId].waterMonsInfo == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
TryGenerateWildMon(gWildMonHeaders[headerId].waterMonsInfo, WILD_AREA_WATER, 0);
|
||||||
|
BattleSetup_StartWildBattle();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool8 DoesCurrentMapHaveFishingMons(void)
|
||||||
|
{
|
||||||
|
u16 headerIdx = GetCurrentMapWildMonHeaderId();
|
||||||
|
if (headerIdx == 0xFFFF)
|
||||||
|
return FALSE;
|
||||||
|
if (gWildMonHeaders[headerIdx].fishingMonsInfo == NULL)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FishingWildEncounter(u8 rod)
|
||||||
|
{
|
||||||
|
GenerateFishingEncounter(gWildMonHeaders[GetCurrentMapWildMonHeaderId()].fishingMonsInfo, rod);
|
||||||
|
IncrementGameStat(GAME_STAT_FISHING_CAPTURES);
|
||||||
|
BattleSetup_StartWildBattle();
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 GetLocalWildMon(bool8 *isWaterMon)
|
||||||
|
{
|
||||||
|
u16 headerId;
|
||||||
|
const struct WildPokemonInfo * landMonsInfo;
|
||||||
|
const struct WildPokemonInfo * waterMonsInfo;
|
||||||
|
|
||||||
|
*isWaterMon = FALSE;
|
||||||
|
headerId = GetCurrentMapWildMonHeaderId();
|
||||||
|
if (headerId == 0xFFFF)
|
||||||
|
return SPECIES_NONE;
|
||||||
|
landMonsInfo = gWildMonHeaders[headerId].landMonsInfo;
|
||||||
|
waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
|
||||||
|
// Neither
|
||||||
|
if (landMonsInfo == NULL && waterMonsInfo == NULL)
|
||||||
|
return SPECIES_NONE;
|
||||||
|
// Land Pokemon
|
||||||
|
else if (landMonsInfo != NULL && waterMonsInfo == NULL)
|
||||||
|
return landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species;
|
||||||
|
// Water Pokemon
|
||||||
|
else if (landMonsInfo == NULL && waterMonsInfo != NULL)
|
||||||
|
{
|
||||||
|
*isWaterMon = TRUE;
|
||||||
|
return waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
|
||||||
|
}
|
||||||
|
// Either land or water Pokemon
|
||||||
|
if ((Random() % 100) < 80)
|
||||||
|
{
|
||||||
|
return landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*isWaterMon = TRUE;
|
||||||
|
return waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 GetLocalWaterMon(void)
|
||||||
|
{
|
||||||
|
u16 headerId = GetCurrentMapWildMonHeaderId();
|
||||||
|
|
||||||
|
if (headerId != 0xFFFF)
|
||||||
|
{
|
||||||
|
const struct WildPokemonInfo * waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
|
||||||
|
|
||||||
|
if (waterMonsInfo)
|
||||||
|
return waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
|
||||||
|
}
|
||||||
|
return SPECIES_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool8 UpdateRepelCounter(void)
|
||||||
|
{
|
||||||
|
u16 steps;
|
||||||
|
|
||||||
|
if (InUnionRoom() == TRUE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (gUnknown_203ADFA == 2)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
steps = VarGet(VAR_REPEL_STEP_COUNT);
|
||||||
|
|
||||||
|
if (steps != 0)
|
||||||
|
{
|
||||||
|
steps--;
|
||||||
|
VarSet(VAR_REPEL_STEP_COUNT, steps);
|
||||||
|
if (steps == 0)
|
||||||
|
{
|
||||||
|
ScriptContext1_SetupScript(EventScript_RepelWoreOff);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool8 IsWildLevelAllowedByRepel(u8 wildLevel)
|
||||||
|
{
|
||||||
|
u8 i;
|
||||||
|
|
||||||
|
if (!VarGet(VAR_REPEL_STEP_COUNT))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
for (i = 0; i < PARTY_SIZE; i++)
|
||||||
|
{
|
||||||
|
if (GetMonData(&gPlayerParty[i], MON_DATA_HP) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG))
|
||||||
|
{
|
||||||
|
u8 ourLevel = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL);
|
||||||
|
|
||||||
|
if (wildLevel < ourLevel)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ApplyFluteEncounterRateMod(u32 *encounterRate)
|
||||||
|
{
|
||||||
|
switch (GetFluteEncounterRateModType())
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
*encounterRate += *encounterRate / 2;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*encounterRate = *encounterRate / 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 GetFluteEncounterRateModType(void)
|
||||||
|
{
|
||||||
|
if (FlagGet(FLAG_SYS_WHITE_FLUTE_ACTIVE) == TRUE)
|
||||||
|
return 1;
|
||||||
|
else if (FlagGet(FLAG_SYS_BLACK_FLUTE_ACTIVE) == TRUE)
|
||||||
|
return 2;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ApplyCleanseTagEncounterRateMod(u32 *encounterRate)
|
||||||
|
{
|
||||||
|
if (IsLeadMonHoldingCleanseTag())
|
||||||
|
*encounterRate = *encounterRate * 2 / 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool8 IsLeadMonHoldingCleanseTag(void)
|
||||||
|
{
|
||||||
|
if (sWildEncounterData.leadMonHeldItem == ITEM_CLEANSE_TAG)
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SeedWildEncounterRng(u16 seed)
|
||||||
|
{
|
||||||
|
sWildEncounterData.rngState = seed;
|
||||||
|
ResetEncounterRateModifiers();
|
||||||
|
}
|
||||||
|
|
||||||
|
static u16 WildEncounterRandom(void)
|
||||||
|
{
|
||||||
|
sWildEncounterData.rngState *= 1103515245;
|
||||||
|
sWildEncounterData.rngState += 12345;
|
||||||
|
return sWildEncounterData.rngState >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 GetMapBaseEncounterCooldown(u8 a0)
|
||||||
|
{
|
||||||
|
u16 headerIdx = GetCurrentMapWildMonHeaderId();
|
||||||
|
if (headerIdx == 0xFFFF)
|
||||||
|
return 0xFF;
|
||||||
|
if (a0 == 1)
|
||||||
|
{
|
||||||
|
if (gWildMonHeaders[headerIdx].landMonsInfo == NULL)
|
||||||
|
return 0xFF;
|
||||||
|
if (gWildMonHeaders[headerIdx].landMonsInfo->encounterRate >= 80)
|
||||||
|
return 0;
|
||||||
|
if (gWildMonHeaders[headerIdx].landMonsInfo->encounterRate < 10)
|
||||||
|
return 8;
|
||||||
|
return 8 - (gWildMonHeaders[headerIdx].landMonsInfo->encounterRate / 10);
|
||||||
|
}
|
||||||
|
if (a0 == 2)
|
||||||
|
{
|
||||||
|
if (gWildMonHeaders[headerIdx].waterMonsInfo == NULL)
|
||||||
|
return 0xFF;
|
||||||
|
if (gWildMonHeaders[headerIdx].waterMonsInfo->encounterRate >= 80)
|
||||||
|
return 0;
|
||||||
|
if (gWildMonHeaders[headerIdx].waterMonsInfo->encounterRate < 10)
|
||||||
|
return 8;
|
||||||
|
return 8 - (gWildMonHeaders[headerIdx].waterMonsInfo->encounterRate / 10);
|
||||||
|
}
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetEncounterRateModifiers(void)
|
||||||
|
{
|
||||||
|
sWildEncounterData.encounterRateBuff = 0;
|
||||||
|
sWildEncounterData.stepsSinceLastEncounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool8 HandleWildEncounterCooldown(u32 currMetatileBehavior)
|
||||||
|
{
|
||||||
|
u8 unk = sub_8058F1C(currMetatileBehavior, 4);
|
||||||
|
u32 minSteps;
|
||||||
|
u32 encRate;
|
||||||
|
if (unk == 0)
|
||||||
|
return FALSE;
|
||||||
|
minSteps = GetMapBaseEncounterCooldown(unk);
|
||||||
|
if (minSteps == 0xFF)
|
||||||
|
return FALSE;
|
||||||
|
minSteps *= 256;
|
||||||
|
encRate = 5 * 256;
|
||||||
|
switch (GetFluteEncounterRateModType())
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
minSteps -= minSteps / 2;
|
||||||
|
encRate += encRate / 2;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
minSteps *= 2;
|
||||||
|
encRate /= 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sWildEncounterData.leadMonHeldItem = GetMonData(&gPlayerParty[0], MON_DATA_HELD_ITEM);
|
||||||
|
if (IsLeadMonHoldingCleanseTag() == TRUE)
|
||||||
|
{
|
||||||
|
minSteps += minSteps / 3;
|
||||||
|
encRate -= encRate / 3;
|
||||||
|
}
|
||||||
|
switch (GetAbilityEncounterRateModType())
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
minSteps *= 2;
|
||||||
|
encRate /= 2;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
minSteps /= 2;
|
||||||
|
encRate *= 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
minSteps /= 256;
|
||||||
|
encRate /= 256;
|
||||||
|
if (sWildEncounterData.stepsSinceLastEncounter >= minSteps)
|
||||||
|
return TRUE;
|
||||||
|
sWildEncounterData.stepsSinceLastEncounter++;
|
||||||
|
if ((Random() % 100) < encRate)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool8 TryStandardWildEncounter(u32 currMetatileBehavior)
|
||||||
|
{
|
||||||
|
if (!HandleWildEncounterCooldown(currMetatileBehavior))
|
||||||
|
{
|
||||||
|
sWildEncounterData.prevMetatileBehavior = sub_8058F1C(currMetatileBehavior, 0);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if (StandardWildEncounter(currMetatileBehavior, sWildEncounterData.prevMetatileBehavior) == TRUE)
|
||||||
|
{
|
||||||
|
sWildEncounterData.encounterRateBuff = 0;
|
||||||
|
sWildEncounterData.stepsSinceLastEncounter = 0;
|
||||||
|
sWildEncounterData.prevMetatileBehavior = sub_8058F1C(currMetatileBehavior, 0);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sWildEncounterData.prevMetatileBehavior = sub_8058F1C(currMetatileBehavior, 0);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddToWildEncounterRateBuff(u8 encounterRate)
|
||||||
|
{
|
||||||
|
if (VarGet(VAR_REPEL_STEP_COUNT) == 0)
|
||||||
|
sWildEncounterData.encounterRateBuff += encounterRate;
|
||||||
|
else
|
||||||
|
sWildEncounterData.encounterRateBuff = 0;
|
||||||
|
}
|
||||||
@@ -265,7 +265,7 @@ static bool32 PokemonInAnyEncounterTableInMap(const struct WildPokemonHeader * d
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
if (PokemonInEncounterTable(data->waterMonsInfo, species, 5))
|
if (PokemonInEncounterTable(data->waterMonsInfo, species, 5))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (PokemonInEncounterTable(data->fishingMonsInfo, species, 12))
|
if (PokemonInEncounterTable(data->fishingMonsInfo, species, 12)) // 10
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (PokemonInEncounterTable(data->rockSmashMonsInfo, species, 5))
|
if (PokemonInEncounterTable(data->rockSmashMonsInfo, species, 5))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
+2
-6
@@ -213,13 +213,9 @@ gUnknown_20386A8: @ 20386A8
|
|||||||
|
|
||||||
.include "src/battle_setup.o"
|
.include "src/battle_setup.o"
|
||||||
.align 2
|
.align 2
|
||||||
|
.include "src/wild_encounter.o"
|
||||||
|
|
||||||
gUnknown_20386D0: @ 20386D0
|
.align 2
|
||||||
.space 0xC
|
|
||||||
|
|
||||||
gUnknown_20386DC: @ 20386DC
|
|
||||||
.space 0x4
|
|
||||||
|
|
||||||
gFieldEffectArguments: @ 20386E0
|
gFieldEffectArguments: @ 20386E0
|
||||||
.space 0x20
|
.space 0x20
|
||||||
|
|
||||||
|
|||||||
+204
-71
@@ -517,7 +517,7 @@ public:
|
|||||||
typedef const_pointer iterator;
|
typedef const_pointer iterator;
|
||||||
typedef const_pointer const_iterator;
|
typedef const_pointer const_iterator;
|
||||||
typedef std::reverse_iterator< const_iterator > reverse_iterator;
|
typedef std::reverse_iterator< const_iterator > reverse_iterator;
|
||||||
typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
|
typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
|
||||||
|
|
||||||
typedef std::size_t size_type;
|
typedef std::size_t size_type;
|
||||||
typedef std::ptrdiff_t difference_type;
|
typedef std::ptrdiff_t difference_type;
|
||||||
@@ -1411,6 +1411,9 @@ enum class ElementNotation {
|
|||||||
Pointer
|
Pointer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Class for lexer configuration.
|
||||||
|
*/
|
||||||
struct LexerConfig {
|
struct LexerConfig {
|
||||||
std::string statement_open {"{%"};
|
std::string statement_open {"{%"};
|
||||||
std::string statement_close {"%}"};
|
std::string statement_close {"%}"};
|
||||||
@@ -1421,6 +1424,9 @@ struct LexerConfig {
|
|||||||
std::string comment_close {"#}"};
|
std::string comment_close {"#}"};
|
||||||
std::string open_chars {"#{"};
|
std::string open_chars {"#{"};
|
||||||
|
|
||||||
|
bool trim_blocks {false};
|
||||||
|
bool lstrip_blocks {false};
|
||||||
|
|
||||||
void update_open_chars() {
|
void update_open_chars() {
|
||||||
open_chars = "";
|
open_chars = "";
|
||||||
if (open_chars.find(line_statement[0]) == std::string::npos) {
|
if (open_chars.find(line_statement[0]) == std::string::npos) {
|
||||||
@@ -1438,6 +1444,9 @@ struct LexerConfig {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Class for parser configuration.
|
||||||
|
*/
|
||||||
struct ParserConfig {
|
struct ParserConfig {
|
||||||
ElementNotation notation {ElementNotation::Dot};
|
ElementNotation notation {ElementNotation::Dot};
|
||||||
};
|
};
|
||||||
@@ -1450,10 +1459,13 @@ struct ParserConfig {
|
|||||||
#ifndef PANTOR_INJA_FUNCTION_STORAGE_HPP
|
#ifndef PANTOR_INJA_FUNCTION_STORAGE_HPP
|
||||||
#define PANTOR_INJA_FUNCTION_STORAGE_HPP
|
#define PANTOR_INJA_FUNCTION_STORAGE_HPP
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
// #include "bytecode.hpp"
|
// #include "bytecode.hpp"
|
||||||
#ifndef PANTOR_INJA_BYTECODE_HPP
|
#ifndef PANTOR_INJA_BYTECODE_HPP
|
||||||
#define PANTOR_INJA_BYTECODE_HPP
|
#define PANTOR_INJA_BYTECODE_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
@@ -1464,7 +1476,7 @@ struct ParserConfig {
|
|||||||
|
|
||||||
namespace inja {
|
namespace inja {
|
||||||
|
|
||||||
using namespace nlohmann;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
|
||||||
struct Bytecode {
|
struct Bytecode {
|
||||||
@@ -1492,6 +1504,7 @@ struct Bytecode {
|
|||||||
GreaterEqual,
|
GreaterEqual,
|
||||||
Less,
|
Less,
|
||||||
LessEqual,
|
LessEqual,
|
||||||
|
At,
|
||||||
Different,
|
Different,
|
||||||
DivisibleBy,
|
DivisibleBy,
|
||||||
Even,
|
Even,
|
||||||
@@ -1594,6 +1607,9 @@ using namespace nlohmann;
|
|||||||
using Arguments = std::vector<const json*>;
|
using Arguments = std::vector<const json*>;
|
||||||
using CallbackFunction = std::function<json(Arguments& args)>;
|
using CallbackFunction = std::function<json(Arguments& args)>;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Class for builtin functions and user-defined callbacks.
|
||||||
|
*/
|
||||||
class FunctionStorage {
|
class FunctionStorage {
|
||||||
public:
|
public:
|
||||||
void add_builtin(nonstd::string_view name, unsigned int num_args, Bytecode::Op op) {
|
void add_builtin(nonstd::string_view name, unsigned int num_args, Bytecode::Op op) {
|
||||||
@@ -1658,6 +1674,9 @@ class FunctionStorage {
|
|||||||
#define PANTOR_INJA_PARSER_HPP
|
#define PANTOR_INJA_PARSER_HPP
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
// #include "bytecode.hpp"
|
// #include "bytecode.hpp"
|
||||||
|
|
||||||
@@ -1678,12 +1697,17 @@ class FunctionStorage {
|
|||||||
#ifndef PANTOR_INJA_TOKEN_HPP
|
#ifndef PANTOR_INJA_TOKEN_HPP
|
||||||
#define PANTOR_INJA_TOKEN_HPP
|
#define PANTOR_INJA_TOKEN_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
// #include "string_view.hpp"
|
// #include "string_view.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace inja {
|
namespace inja {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Helper-class for the inja Parser.
|
||||||
|
*/
|
||||||
struct Token {
|
struct Token {
|
||||||
enum class Kind {
|
enum class Kind {
|
||||||
Text,
|
Text,
|
||||||
@@ -1737,13 +1761,17 @@ struct Token {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // PANTOR_INJA_TOKEN_HPP
|
#endif // PANTOR_INJA_TOKEN_HPP
|
||||||
|
|
||||||
// #include "utils.hpp"
|
// #include "utils.hpp"
|
||||||
#ifndef PANTOR_INJA_UTILS_HPP
|
#ifndef PANTOR_INJA_UTILS_HPP
|
||||||
#define PANTOR_INJA_UTILS_HPP
|
#define PANTOR_INJA_UTILS_HPP
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <fstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
// #include "string_view.hpp"
|
// #include "string_view.hpp"
|
||||||
|
|
||||||
@@ -1755,11 +1783,22 @@ inline void inja_throw(const std::string& type, const std::string& message) {
|
|||||||
throw std::runtime_error("[inja.exception." + type + "] " + message);
|
throw std::runtime_error("[inja.exception." + type + "] " + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::ifstream open_file_or_throw(const std::string& path) {
|
||||||
|
std::ifstream file;
|
||||||
|
file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||||
|
try {
|
||||||
|
file.open(path);
|
||||||
|
} catch(const std::ios_base::failure& e) {
|
||||||
|
inja_throw("file_error", "failed accessing file at '" + path + "'");
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
namespace string_view {
|
namespace string_view {
|
||||||
inline nonstd::string_view slice(nonstd::string_view view, size_t start, size_t end) {
|
inline nonstd::string_view slice(nonstd::string_view view, size_t start, size_t end) {
|
||||||
start = std::min(start, view.size());
|
start = std::min(start, view.size());
|
||||||
end = std::min(std::max(start, end), view.size());
|
end = std::min(std::max(start, end), view.size());
|
||||||
return view.substr(start, end - start); // StringRef(Data + Start, End - Start);
|
return view.substr(start, end - start); // StringRef(Data + Start, End - Start);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::pair<nonstd::string_view, nonstd::string_view> split(nonstd::string_view view, char Separator) {
|
inline std::pair<nonstd::string_view, nonstd::string_view> split(nonstd::string_view view, char Separator) {
|
||||||
@@ -1783,6 +1822,9 @@ namespace string_view {
|
|||||||
|
|
||||||
namespace inja {
|
namespace inja {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Class for lexing an inja Template.
|
||||||
|
*/
|
||||||
class Lexer {
|
class Lexer {
|
||||||
enum class State {
|
enum class State {
|
||||||
Text,
|
Text,
|
||||||
@@ -1831,12 +1873,15 @@ class Lexer {
|
|||||||
|
|
||||||
// try to match one of the opening sequences, and get the close
|
// try to match one of the opening sequences, and get the close
|
||||||
nonstd::string_view open_str = m_in.substr(m_pos);
|
nonstd::string_view open_str = m_in.substr(m_pos);
|
||||||
|
bool must_lstrip = false;
|
||||||
if (inja::string_view::starts_with(open_str, m_config.expression_open)) {
|
if (inja::string_view::starts_with(open_str, m_config.expression_open)) {
|
||||||
m_state = State::ExpressionStart;
|
m_state = State::ExpressionStart;
|
||||||
} else if (inja::string_view::starts_with(open_str, m_config.statement_open)) {
|
} else if (inja::string_view::starts_with(open_str, m_config.statement_open)) {
|
||||||
m_state = State::StatementStart;
|
m_state = State::StatementStart;
|
||||||
|
must_lstrip = m_config.lstrip_blocks;
|
||||||
} else if (inja::string_view::starts_with(open_str, m_config.comment_open)) {
|
} else if (inja::string_view::starts_with(open_str, m_config.comment_open)) {
|
||||||
m_state = State::CommentStart;
|
m_state = State::CommentStart;
|
||||||
|
must_lstrip = m_config.lstrip_blocks;
|
||||||
} else if ((m_pos == 0 || m_in[m_pos - 1] == '\n') &&
|
} else if ((m_pos == 0 || m_in[m_pos - 1] == '\n') &&
|
||||||
inja::string_view::starts_with(open_str, m_config.line_statement)) {
|
inja::string_view::starts_with(open_str, m_config.line_statement)) {
|
||||||
m_state = State::LineStart;
|
m_state = State::LineStart;
|
||||||
@@ -1844,8 +1889,13 @@ class Lexer {
|
|||||||
m_pos += 1; // wasn't actually an opening sequence
|
m_pos += 1; // wasn't actually an opening sequence
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
if (m_pos == m_tok_start) goto again; // don't generate empty token
|
|
||||||
return make_token(Token::Kind::Text);
|
nonstd::string_view text = string_view::slice(m_in, m_tok_start, m_pos);
|
||||||
|
if (must_lstrip)
|
||||||
|
text = clear_final_line_if_whitespace(text);
|
||||||
|
|
||||||
|
if (text.empty()) goto again; // don't generate empty token
|
||||||
|
return Token(Token::Kind::Text, text);
|
||||||
}
|
}
|
||||||
case State::ExpressionStart: {
|
case State::ExpressionStart: {
|
||||||
m_state = State::ExpressionBody;
|
m_state = State::ExpressionBody;
|
||||||
@@ -1872,7 +1922,7 @@ class Lexer {
|
|||||||
case State::LineBody:
|
case State::LineBody:
|
||||||
return scan_body("\n", Token::Kind::LineStatementClose);
|
return scan_body("\n", Token::Kind::LineStatementClose);
|
||||||
case State::StatementBody:
|
case State::StatementBody:
|
||||||
return scan_body(m_config.statement_close, Token::Kind::StatementClose);
|
return scan_body(m_config.statement_close, Token::Kind::StatementClose, m_config.trim_blocks);
|
||||||
case State::CommentBody: {
|
case State::CommentBody: {
|
||||||
// fast-scan to comment close
|
// fast-scan to comment close
|
||||||
size_t end = m_in.substr(m_pos).find(m_config.comment_close);
|
size_t end = m_in.substr(m_pos).find(m_config.comment_close);
|
||||||
@@ -1883,7 +1933,10 @@ class Lexer {
|
|||||||
// return the entire comment in the close token
|
// return the entire comment in the close token
|
||||||
m_state = State::Text;
|
m_state = State::Text;
|
||||||
m_pos += end + m_config.comment_close.size();
|
m_pos += end + m_config.comment_close.size();
|
||||||
return make_token(Token::Kind::CommentClose);
|
Token tok = make_token(Token::Kind::CommentClose);
|
||||||
|
if (m_config.trim_blocks)
|
||||||
|
skip_newline();
|
||||||
|
return tok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1891,7 +1944,7 @@ class Lexer {
|
|||||||
const LexerConfig& get_config() const { return m_config; }
|
const LexerConfig& get_config() const { return m_config; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Token scan_body(nonstd::string_view close, Token::Kind closeKind) {
|
Token scan_body(nonstd::string_view close, Token::Kind closeKind, bool trim = false) {
|
||||||
again:
|
again:
|
||||||
// skip whitespace (except for \n as it might be a close)
|
// skip whitespace (except for \n as it might be a close)
|
||||||
if (m_tok_start >= m_in.size()) return make_token(Token::Kind::Eof);
|
if (m_tok_start >= m_in.size()) return make_token(Token::Kind::Eof);
|
||||||
@@ -1905,7 +1958,10 @@ class Lexer {
|
|||||||
if (inja::string_view::starts_with(m_in.substr(m_tok_start), close)) {
|
if (inja::string_view::starts_with(m_in.substr(m_tok_start), close)) {
|
||||||
m_state = State::Text;
|
m_state = State::Text;
|
||||||
m_pos = m_tok_start + close.size();
|
m_pos = m_tok_start + close.size();
|
||||||
return make_token(closeKind);
|
Token tok = make_token(closeKind);
|
||||||
|
if (trim)
|
||||||
|
skip_newline();
|
||||||
|
return tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip \n
|
// skip \n
|
||||||
@@ -2026,6 +2082,34 @@ class Lexer {
|
|||||||
Token make_token(Token::Kind kind) const {
|
Token make_token(Token::Kind kind) const {
|
||||||
return Token(kind, string_view::slice(m_in, m_tok_start, m_pos));
|
return Token(kind, string_view::slice(m_in, m_tok_start, m_pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void skip_newline() {
|
||||||
|
if (m_pos < m_in.size()) {
|
||||||
|
char ch = m_in[m_pos];
|
||||||
|
if (ch == '\n')
|
||||||
|
m_pos += 1;
|
||||||
|
else if (ch == '\r') {
|
||||||
|
m_pos += 1;
|
||||||
|
if (m_pos < m_in.size() && m_in[m_pos] == '\n')
|
||||||
|
m_pos += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static nonstd::string_view clear_final_line_if_whitespace(nonstd::string_view text)
|
||||||
|
{
|
||||||
|
nonstd::string_view result = text;
|
||||||
|
while (!result.empty()) {
|
||||||
|
char ch = result.back();
|
||||||
|
if (ch == ' ' || ch == '\t')
|
||||||
|
result.remove_suffix(1);
|
||||||
|
else if (ch == '\n' || ch == '\r')
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2036,6 +2120,7 @@ class Lexer {
|
|||||||
#ifndef PANTOR_INJA_TEMPLATE_HPP
|
#ifndef PANTOR_INJA_TEMPLATE_HPP
|
||||||
#define PANTOR_INJA_TEMPLATE_HPP
|
#define PANTOR_INJA_TEMPLATE_HPP
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -2045,6 +2130,9 @@ class Lexer {
|
|||||||
|
|
||||||
namespace inja {
|
namespace inja {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The main inja Template.
|
||||||
|
*/
|
||||||
struct Template {
|
struct Template {
|
||||||
std::vector<Bytecode> bytecodes;
|
std::vector<Bytecode> bytecodes;
|
||||||
std::string content;
|
std::string content;
|
||||||
@@ -2054,7 +2142,7 @@ using TemplateStorage = std::map<std::string, Template>;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // PANTOR_INJA_TEMPLATE_HPP
|
#endif // PANTOR_INJA_TEMPLATE_HPP
|
||||||
|
|
||||||
// #include "token.hpp"
|
// #include "token.hpp"
|
||||||
|
|
||||||
@@ -2068,6 +2156,7 @@ namespace inja {
|
|||||||
|
|
||||||
class ParserStatic {
|
class ParserStatic {
|
||||||
ParserStatic() {
|
ParserStatic() {
|
||||||
|
functions.add_builtin("at", 2, Bytecode::Op::At);
|
||||||
functions.add_builtin("default", 2, Bytecode::Op::Default);
|
functions.add_builtin("default", 2, Bytecode::Op::Default);
|
||||||
functions.add_builtin("divisibleBy", 2, Bytecode::Op::DivisibleBy);
|
functions.add_builtin("divisibleBy", 2, Bytecode::Op::DivisibleBy);
|
||||||
functions.add_builtin("even", 1, Bytecode::Op::Even);
|
functions.add_builtin("even", 1, Bytecode::Op::Even);
|
||||||
@@ -2107,13 +2196,16 @@ class ParserStatic {
|
|||||||
FunctionStorage functions;
|
FunctionStorage functions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Class for parsing an inja Template.
|
||||||
|
*/
|
||||||
class Parser {
|
class Parser {
|
||||||
public:
|
public:
|
||||||
explicit Parser(const ParserConfig& parser_config, const LexerConfig& lexer_config, TemplateStorage& included_templates): m_config(parser_config), m_lexer(lexer_config), m_included_templates(included_templates), m_static(ParserStatic::get_instance()) { }
|
explicit Parser(const ParserConfig& parser_config, const LexerConfig& lexer_config, TemplateStorage& included_templates): m_config(parser_config), m_lexer(lexer_config), m_included_templates(included_templates), m_static(ParserStatic::get_instance()) { }
|
||||||
|
|
||||||
bool parse_expression(Template& tmpl) {
|
bool parse_expression(Template& tmpl) {
|
||||||
if (!parse_expression_and(tmpl)) return false;
|
if (!parse_expression_and(tmpl)) return false;
|
||||||
if (m_tok.kind != Token::Kind::Id || m_tok.text != "or") return true;
|
if (m_tok.kind != Token::Kind::Id || m_tok.text != static_cast<decltype(m_tok.text)>("or")) return true;
|
||||||
get_next_token();
|
get_next_token();
|
||||||
if (!parse_expression_and(tmpl)) return false;
|
if (!parse_expression_and(tmpl)) return false;
|
||||||
append_function(tmpl, Bytecode::Op::Or, 2);
|
append_function(tmpl, Bytecode::Op::Or, 2);
|
||||||
@@ -2122,7 +2214,7 @@ class Parser {
|
|||||||
|
|
||||||
bool parse_expression_and(Template& tmpl) {
|
bool parse_expression_and(Template& tmpl) {
|
||||||
if (!parse_expression_not(tmpl)) return false;
|
if (!parse_expression_not(tmpl)) return false;
|
||||||
if (m_tok.kind != Token::Kind::Id || m_tok.text != "and") return true;
|
if (m_tok.kind != Token::Kind::Id || m_tok.text != static_cast<decltype(m_tok.text)>("and")) return true;
|
||||||
get_next_token();
|
get_next_token();
|
||||||
if (!parse_expression_not(tmpl)) return false;
|
if (!parse_expression_not(tmpl)) return false;
|
||||||
append_function(tmpl, Bytecode::Op::And, 2);
|
append_function(tmpl, Bytecode::Op::And, 2);
|
||||||
@@ -2130,7 +2222,7 @@ class Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool parse_expression_not(Template& tmpl) {
|
bool parse_expression_not(Template& tmpl) {
|
||||||
if (m_tok.kind == Token::Kind::Id && m_tok.text == "not") {
|
if (m_tok.kind == Token::Kind::Id && m_tok.text == static_cast<decltype(m_tok.text)>("not")) {
|
||||||
get_next_token();
|
get_next_token();
|
||||||
if (!parse_expression_not(tmpl)) return false;
|
if (!parse_expression_not(tmpl)) return false;
|
||||||
append_function(tmpl, Bytecode::Op::Not, 1);
|
append_function(tmpl, Bytecode::Op::Not, 1);
|
||||||
@@ -2145,7 +2237,7 @@ class Parser {
|
|||||||
Bytecode::Op op;
|
Bytecode::Op op;
|
||||||
switch (m_tok.kind) {
|
switch (m_tok.kind) {
|
||||||
case Token::Kind::Id:
|
case Token::Kind::Id:
|
||||||
if (m_tok.text == "in")
|
if (m_tok.text == static_cast<decltype(m_tok.text)>("in"))
|
||||||
op = Bytecode::Op::In;
|
op = Bytecode::Op::In;
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
@@ -2233,7 +2325,9 @@ class Parser {
|
|||||||
append_callback(tmpl, func_token.text, num_args);
|
append_callback(tmpl, func_token.text, num_args);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (m_tok.text == "true" || m_tok.text == "false" || m_tok.text == "null") {
|
} else if (m_tok.text == static_cast<decltype(m_tok.text)>("true") ||
|
||||||
|
m_tok.text == static_cast<decltype(m_tok.text)>("false") ||
|
||||||
|
m_tok.text == static_cast<decltype(m_tok.text)>("null")) {
|
||||||
// true, false, null are json literals
|
// true, false, null are json literals
|
||||||
if (brace_level == 0 && bracket_level == 0) {
|
if (brace_level == 0 && bracket_level == 0) {
|
||||||
json_first = m_tok.text;
|
json_first = m_tok.text;
|
||||||
@@ -2312,7 +2406,7 @@ class Parser {
|
|||||||
bool parse_statement(Template& tmpl, nonstd::string_view path) {
|
bool parse_statement(Template& tmpl, nonstd::string_view path) {
|
||||||
if (m_tok.kind != Token::Kind::Id) return false;
|
if (m_tok.kind != Token::Kind::Id) return false;
|
||||||
|
|
||||||
if (m_tok.text == "if") {
|
if (m_tok.text == static_cast<decltype(m_tok.text)>("if")) {
|
||||||
get_next_token();
|
get_next_token();
|
||||||
|
|
||||||
// evaluate expression
|
// evaluate expression
|
||||||
@@ -2323,7 +2417,7 @@ class Parser {
|
|||||||
|
|
||||||
// conditional jump; destination will be filled in by else or endif
|
// conditional jump; destination will be filled in by else or endif
|
||||||
tmpl.bytecodes.emplace_back(Bytecode::Op::ConditionalJump);
|
tmpl.bytecodes.emplace_back(Bytecode::Op::ConditionalJump);
|
||||||
} else if (m_tok.text == "endif") {
|
} else if (m_tok.text == static_cast<decltype(m_tok.text)>("endif")) {
|
||||||
if (m_if_stack.empty()) {
|
if (m_if_stack.empty()) {
|
||||||
inja_throw("parser_error", "endif without matching if");
|
inja_throw("parser_error", "endif without matching if");
|
||||||
}
|
}
|
||||||
@@ -2342,7 +2436,7 @@ class Parser {
|
|||||||
|
|
||||||
// pop if stack
|
// pop if stack
|
||||||
m_if_stack.pop_back();
|
m_if_stack.pop_back();
|
||||||
} else if (m_tok.text == "else") {
|
} else if (m_tok.text == static_cast<decltype(m_tok.text)>("else")) {
|
||||||
if (m_if_stack.empty())
|
if (m_if_stack.empty())
|
||||||
inja_throw("parser_error", "else without matching if");
|
inja_throw("parser_error", "else without matching if");
|
||||||
auto& if_data = m_if_stack.back();
|
auto& if_data = m_if_stack.back();
|
||||||
@@ -2358,7 +2452,7 @@ class Parser {
|
|||||||
if_data.prev_cond_jump = std::numeric_limits<unsigned int>::max();
|
if_data.prev_cond_jump = std::numeric_limits<unsigned int>::max();
|
||||||
|
|
||||||
// chained else if
|
// chained else if
|
||||||
if (m_tok.kind == Token::Kind::Id && m_tok.text == "if") {
|
if (m_tok.kind == Token::Kind::Id && m_tok.text == static_cast<decltype(m_tok.text)>("if")) {
|
||||||
get_next_token();
|
get_next_token();
|
||||||
|
|
||||||
// evaluate expression
|
// evaluate expression
|
||||||
@@ -2370,7 +2464,7 @@ class Parser {
|
|||||||
// conditional jump; destination will be filled in by else or endif
|
// conditional jump; destination will be filled in by else or endif
|
||||||
tmpl.bytecodes.emplace_back(Bytecode::Op::ConditionalJump);
|
tmpl.bytecodes.emplace_back(Bytecode::Op::ConditionalJump);
|
||||||
}
|
}
|
||||||
} else if (m_tok.text == "for") {
|
} else if (m_tok.text == static_cast<decltype(m_tok.text)>("for")) {
|
||||||
get_next_token();
|
get_next_token();
|
||||||
|
|
||||||
// options: for a in arr; for a, b in obj
|
// options: for a in arr; for a, b in obj
|
||||||
@@ -2389,7 +2483,7 @@ class Parser {
|
|||||||
get_next_token();
|
get_next_token();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_tok.kind != Token::Kind::Id || m_tok.text != "in")
|
if (m_tok.kind != Token::Kind::Id || m_tok.text != static_cast<decltype(m_tok.text)>("in"))
|
||||||
inja_throw("parser_error",
|
inja_throw("parser_error",
|
||||||
"expected 'in', got '" + m_tok.describe() + "'");
|
"expected 'in', got '" + m_tok.describe() + "'");
|
||||||
get_next_token();
|
get_next_token();
|
||||||
@@ -2403,7 +2497,7 @@ class Parser {
|
|||||||
tmpl.bytecodes.back().value = key_token.text;
|
tmpl.bytecodes.back().value = key_token.text;
|
||||||
}
|
}
|
||||||
tmpl.bytecodes.back().str = static_cast<std::string>(value_token.text);
|
tmpl.bytecodes.back().str = static_cast<std::string>(value_token.text);
|
||||||
} else if (m_tok.text == "endfor") {
|
} else if (m_tok.text == static_cast<decltype(m_tok.text)>("endfor")) {
|
||||||
get_next_token();
|
get_next_token();
|
||||||
if (m_loop_stack.empty()) {
|
if (m_loop_stack.empty()) {
|
||||||
inja_throw("parser_error", "endfor without matching for");
|
inja_throw("parser_error", "endfor without matching for");
|
||||||
@@ -2415,7 +2509,7 @@ class Parser {
|
|||||||
tmpl.bytecodes.emplace_back(Bytecode::Op::EndLoop);
|
tmpl.bytecodes.emplace_back(Bytecode::Op::EndLoop);
|
||||||
tmpl.bytecodes.back().args = m_loop_stack.back() + 1; // loop body
|
tmpl.bytecodes.back().args = m_loop_stack.back() + 1; // loop body
|
||||||
m_loop_stack.pop_back();
|
m_loop_stack.pop_back();
|
||||||
} else if (m_tok.text == "include") {
|
} else if (m_tok.text == static_cast<decltype(m_tok.text)>("include")) {
|
||||||
get_next_token();
|
get_next_token();
|
||||||
|
|
||||||
if (m_tok.kind != Token::Kind::String) {
|
if (m_tok.kind != Token::Kind::String) {
|
||||||
@@ -2431,8 +2525,10 @@ class Parser {
|
|||||||
}
|
}
|
||||||
// sys::path::remove_dots(pathname, true, sys::path::Style::posix);
|
// sys::path::remove_dots(pathname, true, sys::path::Style::posix);
|
||||||
|
|
||||||
Template include_template = parse_template(pathname);
|
if (m_included_templates.find(pathname) == m_included_templates.end()) {
|
||||||
m_included_templates.emplace(pathname, include_template);
|
Template include_template = parse_template(pathname);
|
||||||
|
m_included_templates.emplace(pathname, include_template);
|
||||||
|
}
|
||||||
|
|
||||||
// generate a reference bytecode
|
// generate a reference bytecode
|
||||||
tmpl.bytecodes.emplace_back(Bytecode::Op::Include, json(pathname), Bytecode::Flag::ValueImmediate);
|
tmpl.bytecodes.emplace_back(Bytecode::Op::Include, json(pathname), Bytecode::Flag::ValueImmediate);
|
||||||
@@ -2552,10 +2648,10 @@ class Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string load_file(nonstd::string_view filename) {
|
std::string load_file(nonstd::string_view filename) {
|
||||||
std::ifstream file(static_cast<std::string>(filename));
|
std::ifstream file = open_file_or_throw(static_cast<std::string>(filename));
|
||||||
std::string text((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
std::string text((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const ParserConfig& m_config;
|
const ParserConfig& m_config;
|
||||||
@@ -2605,6 +2701,7 @@ class Parser {
|
|||||||
#if __cplusplus < 201402L
|
#if __cplusplus < 201402L
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -2655,6 +2752,9 @@ namespace stdinja = std;
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
@@ -2679,6 +2779,9 @@ inline nonstd::string_view convert_dot_to_json_pointer(nonstd::string_view dot,
|
|||||||
return nonstd::string_view(out.data(), out.size());
|
return nonstd::string_view(out.data(), out.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Class for rendering a Template with data.
|
||||||
|
*/
|
||||||
class Renderer {
|
class Renderer {
|
||||||
std::vector<const json*>& get_args(const Bytecode& bc) {
|
std::vector<const json*>& get_args(const Bytecode& bc) {
|
||||||
m_tmp_args.clear();
|
m_tmp_args.clear();
|
||||||
@@ -2765,7 +2868,7 @@ class Renderer {
|
|||||||
LoopLevel& level = m_loop_stack.back();
|
LoopLevel& level = m_loop_stack.back();
|
||||||
|
|
||||||
if (level.loop_type == LoopLevel::Type::Array) {
|
if (level.loop_type == LoopLevel::Type::Array) {
|
||||||
level.data[static_cast<std::string>(level.value_name)] = level.values.at(level.index); // *level.it;
|
level.data[static_cast<std::string>(level.value_name)] = level.values.at(level.index); // *level.it;
|
||||||
auto& loopData = level.data["loop"];
|
auto& loopData = level.data["loop"];
|
||||||
loopData["index"] = level.index;
|
loopData["index"] = level.index;
|
||||||
loopData["index1"] = level.index + 1;
|
loopData["index1"] = level.index + 1;
|
||||||
@@ -2787,8 +2890,8 @@ class Renderer {
|
|||||||
enum class Type { Map, Array };
|
enum class Type { Map, Array };
|
||||||
|
|
||||||
Type loop_type;
|
Type loop_type;
|
||||||
nonstd::string_view key_name; // variable name for keys
|
nonstd::string_view key_name; // variable name for keys
|
||||||
nonstd::string_view value_name; // variable name for values
|
nonstd::string_view value_name; // variable name for values
|
||||||
json data; // data with loop info added
|
json data; // data with loop info added
|
||||||
|
|
||||||
json values; // values to iterate over
|
json values; // values to iterate over
|
||||||
@@ -2800,8 +2903,8 @@ class Renderer {
|
|||||||
// loop over map
|
// loop over map
|
||||||
using KeyValue = std::pair<nonstd::string_view, json*>;
|
using KeyValue = std::pair<nonstd::string_view, json*>;
|
||||||
using MapValues = std::vector<KeyValue>;
|
using MapValues = std::vector<KeyValue>;
|
||||||
MapValues map_values; // values to iterate over
|
MapValues map_values; // values to iterate over
|
||||||
MapValues::iterator map_it; // iterator over values
|
MapValues::iterator map_it; // iterator over values
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2835,11 +2938,11 @@ class Renderer {
|
|||||||
}
|
}
|
||||||
case Bytecode::Op::PrintValue: {
|
case Bytecode::Op::PrintValue: {
|
||||||
const json& val = *get_args(bc)[0];
|
const json& val = *get_args(bc)[0];
|
||||||
if (val.is_string())
|
if (val.is_string()) {
|
||||||
os << val.get_ref<const std::string&>();
|
os << val.get_ref<const std::string&>();
|
||||||
else
|
} else {
|
||||||
os << val.dump();
|
os << val.dump();
|
||||||
// val.dump(os);
|
}
|
||||||
pop_args(bc);
|
pop_args(bc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2870,7 +2973,15 @@ class Renderer {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Bytecode::Op::Length: {
|
case Bytecode::Op::Length: {
|
||||||
auto result = get_args(bc)[0]->size();
|
const json& val = *get_args(bc)[0];
|
||||||
|
|
||||||
|
int result;
|
||||||
|
if (val.is_string()) {
|
||||||
|
result = val.get_ref<const std::string&>().length();
|
||||||
|
} else {
|
||||||
|
result = val.size();
|
||||||
|
}
|
||||||
|
|
||||||
pop_args(bc);
|
pop_args(bc);
|
||||||
m_stack.emplace_back(result);
|
m_stack.emplace_back(result);
|
||||||
break;
|
break;
|
||||||
@@ -2882,6 +2993,13 @@ class Renderer {
|
|||||||
m_stack.emplace_back(std::move(result));
|
m_stack.emplace_back(std::move(result));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Bytecode::Op::At: {
|
||||||
|
auto args = get_args(bc);
|
||||||
|
auto result = args[0]->at(args[1]->get<int>());
|
||||||
|
pop_args(bc);
|
||||||
|
m_stack.emplace_back(result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Bytecode::Op::First: {
|
case Bytecode::Op::First: {
|
||||||
auto result = get_args(bc)[0]->front();
|
auto result = get_args(bc)[0]->front();
|
||||||
pop_args(bc);
|
pop_args(bc);
|
||||||
@@ -3091,7 +3209,7 @@ class Renderer {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Bytecode::Op::Include:
|
case Bytecode::Op::Include:
|
||||||
Renderer(m_included_templates, m_callbacks).render_to(os, m_included_templates.find(get_imm(bc)->get_ref<const std::string&>())->second, data);
|
Renderer(m_included_templates, m_callbacks).render_to(os, m_included_templates.find(get_imm(bc)->get_ref<const std::string&>())->second, *m_data);
|
||||||
break;
|
break;
|
||||||
case Bytecode::Op::Callback: {
|
case Bytecode::Op::Callback: {
|
||||||
auto callback = m_callbacks.find_callback(bc.str, bc.args);
|
auto callback = m_callbacks.find_callback(bc.str, bc.args);
|
||||||
@@ -3216,12 +3334,17 @@ class Renderer {
|
|||||||
|
|
||||||
// #include "template.hpp"
|
// #include "template.hpp"
|
||||||
|
|
||||||
|
// #include "utils.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace inja {
|
namespace inja {
|
||||||
|
|
||||||
using namespace nlohmann;
|
using namespace nlohmann;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Class for changing the configuration.
|
||||||
|
*/
|
||||||
class Environment {
|
class Environment {
|
||||||
class Impl {
|
class Impl {
|
||||||
public:
|
public:
|
||||||
@@ -3238,7 +3361,7 @@ class Environment {
|
|||||||
std::unique_ptr<Impl> m_impl;
|
std::unique_ptr<Impl> m_impl;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Environment(): Environment("./") { }
|
Environment(): Environment("") { }
|
||||||
|
|
||||||
explicit Environment(const std::string& global_path): m_impl(stdinja::make_unique<Impl>()) {
|
explicit Environment(const std::string& global_path): m_impl(stdinja::make_unique<Impl>()) {
|
||||||
m_impl->input_path = global_path;
|
m_impl->input_path = global_path;
|
||||||
@@ -3277,6 +3400,16 @@ class Environment {
|
|||||||
m_impl->lexer_config.update_open_chars();
|
m_impl->lexer_config.update_open_chars();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets whether to remove the first newline after a block
|
||||||
|
void set_trim_blocks(bool trim_blocks) {
|
||||||
|
m_impl->lexer_config.trim_blocks = trim_blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets whether to strip the spaces and tabs from the start of a line to a block
|
||||||
|
void set_lstrip_blocks(bool lstrip_blocks) {
|
||||||
|
m_impl->lexer_config.lstrip_blocks = lstrip_blocks;
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the element notation syntax
|
/// Sets the element notation syntax
|
||||||
void set_element_notation(ElementNotation notation) {
|
void set_element_notation(ElementNotation notation) {
|
||||||
m_impl->parser_config.notation = notation;
|
m_impl->parser_config.notation = notation;
|
||||||
@@ -3290,8 +3423,8 @@ class Environment {
|
|||||||
|
|
||||||
Template parse_template(const std::string& filename) {
|
Template parse_template(const std::string& filename) {
|
||||||
Parser parser(m_impl->parser_config, m_impl->lexer_config, m_impl->included_templates);
|
Parser parser(m_impl->parser_config, m_impl->lexer_config, m_impl->included_templates);
|
||||||
return parser.parse_template(m_impl->input_path + static_cast<std::string>(filename));
|
return parser.parse_template(m_impl->input_path + static_cast<std::string>(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string render(nonstd::string_view input, const json& data) {
|
std::string render(nonstd::string_view input, const json& data) {
|
||||||
return render(parse(input), data);
|
return render(parse(input), data);
|
||||||
@@ -3304,35 +3437,35 @@ class Environment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string render_file(const std::string& filename, const json& data) {
|
std::string render_file(const std::string& filename, const json& data) {
|
||||||
return render(parse_template(filename), data);
|
return render(parse_template(filename), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string render_file_with_json_file(const std::string& filename, const std::string& filename_data) {
|
std::string render_file_with_json_file(const std::string& filename, const std::string& filename_data) {
|
||||||
const json data = load_json(filename_data);
|
const json data = load_json(filename_data);
|
||||||
return render_file(filename, data);
|
return render_file(filename, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(const std::string& filename, const json& data, const std::string& filename_out) {
|
void write(const std::string& filename, const json& data, const std::string& filename_out) {
|
||||||
std::ofstream file(m_impl->output_path + filename_out);
|
std::ofstream file(m_impl->output_path + filename_out);
|
||||||
file << render_file(filename, data);
|
file << render_file(filename, data);
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(const Template& temp, const json& data, const std::string& filename_out) {
|
void write(const Template& temp, const json& data, const std::string& filename_out) {
|
||||||
std::ofstream file(m_impl->output_path + filename_out);
|
std::ofstream file(m_impl->output_path + filename_out);
|
||||||
file << render(temp, data);
|
file << render(temp, data);
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_with_json_file(const std::string& filename, const std::string& filename_data, const std::string& filename_out) {
|
void write_with_json_file(const std::string& filename, const std::string& filename_data, const std::string& filename_out) {
|
||||||
const json data = load_json(filename_data);
|
const json data = load_json(filename_data);
|
||||||
write(filename, data, filename_out);
|
write(filename, data, filename_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_with_json_file(const Template& temp, const std::string& filename_data, const std::string& filename_out) {
|
void write_with_json_file(const Template& temp, const std::string& filename_data, const std::string& filename_out) {
|
||||||
const json data = load_json(filename_data);
|
const json data = load_json(filename_data);
|
||||||
write(temp, data, filename_out);
|
write(temp, data, filename_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& render_to(std::ostream& os, const Template& tmpl, const json& data) {
|
std::ostream& render_to(std::ostream& os, const Template& tmpl, const json& data) {
|
||||||
Renderer(m_impl->included_templates, m_impl->callbacks).render_to(os, tmpl, data);
|
Renderer(m_impl->included_templates, m_impl->callbacks).render_to(os, tmpl, data);
|
||||||
@@ -3341,15 +3474,15 @@ class Environment {
|
|||||||
|
|
||||||
std::string load_file(const std::string& filename) {
|
std::string load_file(const std::string& filename) {
|
||||||
Parser parser(m_impl->parser_config, m_impl->lexer_config, m_impl->included_templates);
|
Parser parser(m_impl->parser_config, m_impl->lexer_config, m_impl->included_templates);
|
||||||
return parser.load_file(m_impl->input_path + filename);
|
return parser.load_file(m_impl->input_path + filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
json load_json(const std::string& filename) {
|
json load_json(const std::string& filename) {
|
||||||
std::ifstream file(m_impl->input_path + filename);
|
std::ifstream file = open_file_or_throw(m_impl->input_path + filename);
|
||||||
json j;
|
json j;
|
||||||
file >> j;
|
file >> j;
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_callback(const std::string& name, unsigned int numArgs, const CallbackFunction& callback) {
|
void add_callback(const std::string& name, unsigned int numArgs, const CallbackFunction& callback) {
|
||||||
m_impl->callbacks.add_callback(name, numArgs, callback);
|
m_impl->callbacks.add_callback(name, numArgs, callback);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
using std::string;
|
using std::string; using std::to_string;
|
||||||
|
|
||||||
#include <inja.hpp>
|
#include <inja.hpp>
|
||||||
using namespace inja;
|
using namespace inja;
|
||||||
@@ -36,7 +36,14 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// Add custom command callbacks.
|
// Add custom command callbacks.
|
||||||
env.add_callback("doNotModifyHeader", 0, [jsonfilepath, templateFilepath](Arguments& args) {
|
env.add_callback("doNotModifyHeader", 0, [jsonfilepath, templateFilepath](Arguments& args) {
|
||||||
return "//\n// DO NOT MODIFY THIS FILE! IT IS AUTO-GENERATED FROM " + jsonfilepath +" and Inja template " + templateFilepath + "\n//\n";
|
return "//\n// DO NOT MODIFY THIS FILE! It is auto-generated from " + jsonfilepath +" and Inja template " + templateFilepath + "\n//\n";
|
||||||
|
});
|
||||||
|
|
||||||
|
env.add_callback("subtract", 2, [](Arguments& args) {
|
||||||
|
int minuend = args.at(0)->get<int>();
|
||||||
|
int subtrahend = args.at(1)->get<int>();
|
||||||
|
|
||||||
|
return minuend - subtrahend;
|
||||||
});
|
});
|
||||||
|
|
||||||
env.add_callback("setVar", 2, [=](Arguments& args) {
|
env.add_callback("setVar", 2, [=](Arguments& args) {
|
||||||
@@ -46,6 +53,13 @@ int main(int argc, char *argv[])
|
|||||||
return "";
|
return "";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
env.add_callback("setVarInt", 2, [=](Arguments& args) {
|
||||||
|
string key = args.at(0)->get<string>();
|
||||||
|
string value = to_string(args.at(1)->get<int>());
|
||||||
|
set_custom_var(key, value);
|
||||||
|
return "";
|
||||||
|
});
|
||||||
|
|
||||||
env.add_callback("getVar", 1, [=](Arguments& args) {
|
env.add_callback("getVar", 1, [=](Arguments& args) {
|
||||||
string key = args.at(0)->get<string>();
|
string key = args.at(0)->get<string>();
|
||||||
return get_custom_var(key);
|
return get_custom_var(key);
|
||||||
@@ -67,7 +81,6 @@ int main(int argc, char *argv[])
|
|||||||
return rawValue.erase(0, prefix.length());
|
return rawValue.erase(0, prefix.length());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add custom command callbacks.
|
|
||||||
env.add_callback("removeSuffix", 2, [](Arguments& args) {
|
env.add_callback("removeSuffix", 2, [](Arguments& args) {
|
||||||
string rawValue = args.at(0)->get<string>();
|
string rawValue = args.at(0)->get<string>();
|
||||||
string suffix = args.at(1)->get<string>();
|
string suffix = args.at(1)->get<string>();
|
||||||
@@ -78,6 +91,11 @@ int main(int argc, char *argv[])
|
|||||||
return rawValue.substr(0, i);
|
return rawValue.substr(0, i);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// single argument is a json object
|
||||||
|
env.add_callback("isEmpty", 1, [](Arguments& args) {
|
||||||
|
return args.at(0)->empty();
|
||||||
|
});
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
env.write_with_json_file(templateFilepath, jsonfilepath, outputFilepath);
|
env.write_with_json_file(templateFilepath, jsonfilepath, outputFilepath);
|
||||||
|
|||||||
Reference in New Issue
Block a user