Merge branch 'upcoming' into expansion-1.11.4

This commit is contained in:
Hedara 2025-05-30 20:45:19 +02:00
commit 09ee1d0b2d
474 changed files with 49945 additions and 33131 deletions

View File

@ -5,9 +5,8 @@ body:
- type: markdown
attributes:
value: |
Please fill in all required fields with as many details as possible.
Please fill in all fields with as many details as possible.
Once your bug is posted, make sure you and your collaborators are added to `CREDITS.md` by [tagging the bot on GitHub](https://github.com/rh-hideout/pokeemerald-expansion/wiki/CREDITS.md-Frequently-Asked-Questions). EVERY contribution matters, even reporting bugs!
- type: textarea
id: description
attributes:
label: Description

View File

@ -5,7 +5,7 @@ body:
- type: markdown
attributes:
value: |
Please fill in all required fields with as many details as possible.
Please fill in all fields with as many details as possible.
Once your bug is posted, make sure you and your collaborators are added to `CREDITS.md` by [tagging the bot on GitHub](https://github.com/rh-hideout/pokeemerald-expansion/wiki/CREDITS.md-Frequently-Asked-Questions). EVERY contribution matters, even reporting bugs!
- type: textarea
id: description

View File

@ -5,7 +5,7 @@ body:
- type: markdown
attributes:
value: |
Please fill in all required fields with as many details as possible.
Please fill in all fields with as many details as possible.
Once your feature request is posted, make sure you and your collaborators are added to `CREDITS.md` by [tagging the bot on GitHub](https://github.com/rh-hideout/pokeemerald-expansion/wiki/CREDITS.md-Frequently-Asked-Questions). EVERY contribution matters, even requesting issues!
- type: textarea

View File

@ -5,7 +5,7 @@ body:
- type: markdown
attributes:
value: |
Please fill in all required fields with as many details as possible.
Please fill in all fields with as many details as possible.
Once your bug is posted, make sure you and your collaborators are added to `CREDITS.md` by [tagging the bot on GitHub](https://github.com/rh-hideout/pokeemerald-expansion/wiki/CREDITS.md-Frequently-Asked-Questions). EVERY contribution matters, even creating issues!
- type: textarea
id: description

1
.gitignore vendored
View File

@ -45,3 +45,4 @@ tools/trainerproc/trainerproc
*.smol
*.fastSmol
*.smolTM
__pycache__

142
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,142 @@
# Contributing to pokeemerald-expansion
First off, thanks for helping improve `pokeemerald-expansion`! ❤️
All contributions are encouraged and valued. Please make sure to read the relevant section before making your contribution! It will make it a lot easier for you and the maintainers. We're excited to see your contributions. 🎉
## Bug Reports
We use [GitHub](https://github.com/rh-hideout/pokeemerald-expansion/issues?q=sort%3Aupdated-desc+is%3Aissue+is%3Aopen+label%3Abug) issues to track bugs.
### What should I do before making a bug report?
- Does your bug occur on the latest unmodified (clean) version of the [`upcoming`](https://github.com/rh-hideout/pokeemerald-expansion/tree/upcoming) or [`master`](https://github.com/rh-hideout/pokeemerald-expansion/tree/master) branch? If not, please do not submit a report - the issue is most likely one introduced by your game.
- Has somebody else already found this issue? This is best done by searching the [bug tracker](https://github.com/rh-hideout/pokeemerald-expansion/issues?q=label%3Abug) to see if anybody else reported it. If there is already an issue, replying to the exsting issue with more information can help solve the problem.
### How do I submit a bug report?
If you run into an issue with the project, open an [issue](https://github.com/rh-hideout/pokeemerald-expansion/issues/new).
The best bug reports have enough information that we won't have to contact you for more information. We welcome all efforts to improve pokeemerald-expansion, but would be very grateful if you completed as much of the checklist as possible in your bug report. This will help other contributiors fix your issue.
### What happens after I submit a bug report?
- A maintainer will [label](https://github.com/rh-hideout/pokeemerald-expansion/labels) the bug report.
- A maintainer will try to reproduce the bug with your provided steps.
- If there are no reproduction steps or no obvious way to reproduce the issue, somebody will ask you for those steps. Until the bug can be reproduced, the bug will retain the `bug:unconfirmed` label. Unconfirmed bugs are less likely get fixed.
- If the team is able to reproduce the bug, it will be labeled `bug:confirmed`, and the bug will be left to be [fixed by someone](#Pull-Requests).
- If the issue is particularly game-breaking, a maintainer will add it to a future version's [milestone](), meaning that version will not be released until the problem is solved.
## Feature Requests
This section guides you through submitting a feature request for pokeemerald-expansion, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions.
- We use [GitHub](https://github.com/rh-hideout/pokeemerald-expansion/issues?q=sort%3Aupdated-desc+is%3Aissue+is%3Aopen+label%3Afeature-request) issues to track feature requests.
### What should I do before making a feature request?
- Make sure your request is in [pokeemerald-expansion's scope](docs/team_procedures/scope.md) - if it is not clear if something is in scope, you can start a discussion thread in the [#pr-discussions](https://discord.com/channels/419213663107416084/1102784418369785948) channel of the [the RHH Discord Server](https://discord.gg/6CzjAG6GZk).
### What should I do before making a feature request?
- Read the [documentation](https://rh-hideout.github.io/pokeemerald-expansion/) to find out if the functionality is already covered, maybe by an individual configuration.
- Perform a [search](https://github.com/rh-hideout/pokeemerald-expansion/issues) to see if the feature has already been requested. If it has, add a comment to the existing issue instead of opening a new one.
### How do I submit a feature request?
To request a feature to be added to the project, open a [feature request](https://github.com/rh-hideout/pokeemerald-expansion/issues/new).
### What happens after I submit a feature request?
- A maintainer will [label](https://github.com/rh-hideout/pokeemerald-expansion/labels) the issue.
- If the feature request is out of [scope](docs/team_procedures/scope.md), it will be closed.
- if the request is in scope, any other contributor can volunteer to [fufill it via a pull request](#Pull-Requests). When the request is filled, the request will be closed.
## Pull Requests
If you have read all of this and still need help, feel free to start a thread in #pr-discussions of the Discord server or ask questions in #expansion-dev.
### What should I do before starting a pull request?
- If you're new to git and GitHub, [Team Aqua's Asset Repo](https://github.com/Pawkkie/Team-Aquas-Asset-Repo/) has a [guide on forking and cloning the repository](https://github.com/Pawkkie/Team-Aquas-Asset-Repo/wiki/The-Basics-of-GitHub). Make sure you have a [local copy](INSTALL.md) of `pokeemerald-expansion`.
- Make sure your contribution is in [scope](docs/team_procedures/scope.md) - if it is not clear if something is in scope, you can start a discussion thread in the [#pr-discussions](https://discord.com/channels/419213663107416084/1102784418369785948) channel of the [the RHH Discord Server!](https://discord.gg/6CzjAG6GZk).
- Choose a branch to contribute your PR to:
- **`master`**: Fixes for bugs that are currently present in the `master` branch.
- **`upcoming`**: All other pull requests.
- Create a new branch from the most recent version of the branch you've chosen.
- If your contribution introduces, removes, or changes a lot of existing code, we reccomend getting a maintainer to agree to review it before you start on the work! We have a table that lists all [current maintainers and their areas of expertise](#maintainers).
### How do I submit a pull request?
#### 1. Get a working local copy
If you haven't already, follow [INSTALL.md](INSTALL.md) to get a working local copy of `pokeemerald-expansion`.
#### 2. Set RHH as a remote
This will designate the main `pokeemerald-expansion` repository as a remote.
```bash
git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion # You can replace RHH with anything you want. This tutorial assumes you used RHH.
```
#### 3. Create a new branch
This will create a new branch and switch to it.
```bash
git switch -c newFeature # the name newFeature can be anything you want. This tutorial assumes you used newFeature.
```
#### 4. Copy your target branch to your new branch
This will change your new branch to match the latest version of your chosen target branch.
```bash
git reset --hard upcoming # If your PR is going to target master, replace upcoming with master.
```
#### 5. Implement your code
All of your work should go on this new, clean branch. If you already started work on a different branch, you can [cherry-pick](https://git-scm.com/docs/git-cherry-pick) you old commits onto this new branch, or just copy and paste the changes from the original files.
##### Popular Features / Feature Branches
If you are implementing functionality from a known community feature branch, it is **strongly** recommended that you open a discussion thread _before_ starting. There are some situations where maintainers would ask you to use the existing feature branch as a base, and others where maintainers would want a feature to be written from scratch.
This changes on a case by case basis.
#### 6. Push your changes
When you push your first commit, you'll need to push the new branch to the remote repo.
```bash
git push --set-upstream origin newFeature
```
#### 7. Open Pull Request
Once your work is complete and pushed to the branch on Github, you can open a [pull request from your branch](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork), targeting the branch you've chosen from `pokeemerald-expansion`. Please fill out the pull request description as completely as possible.
### What happens after I submit a pull request?
A maintainer will then assign themselves as a reviewer of your pull request, and may provide feedback in the form of a PR review.
Contributors are responsible for responding to and updating their branch by addressing the feedback in the review. Contributors are also responsible for making sure the branch passes the checklist at all times.
Once a maintainer has begun reviewing your PR, **please** do not force-push new changes - normal pushes are fine. Do not worry about git history - we squash most incoming changes.
Maintainers will measure the submitted pull request against a [merge checklist](docs/team_procedures/merge_checklist.md).
Once all items on the merge checklist are true, the branch will be merged in.
## Maintainers
This list was last updated 2025 April 1.
| Name | Discord | Currently Active | Areas of Expertise |
| --- | --- | --- | --- |
| [Alex](https://github.com/AlexOn1ine) | rainonline | ✅ | Battle Engine, Battle AI
| [Egg](https://github.com/DizzyEggg) | egg9255 | ✅ | Battle Engine, Battle AI
| [ghoulslash](https://github.com/ghoulslash) | ghoulslash | ✅ | Dexnav, Overworld, Battle Engine
| [Jasper](https://github.com/Bassoonian) | bassoonian | ✅ | Berries, Day / Night System, Followers, Feature Branches
| [MGriffin](https://github.com/mrgriffin) | mgriffin | ✅ | Tests, Trainer Control
| [psf](https://github.com/pkmnsnfrn) | pkmnsnfrn | ✅ | Rematches, Difficulty, Trainer Slides, Fake RTC, Fishing Minigames, Imperial / Metric, OW Item Balls, Sky Battles
| [Hedara](https://github.com/hedara90) | hedara | ✅ | Compression, Sprites
| [Pawkkie](https://github.com/Pawkkie) | pawkkie | ✅ | Battle AI
| [SBird](https://github.com/SBird1337) | karathan | ✅ | Dynamic Multichoice, Damage Calculation, Animations, Trainer Control, Tests
| [Agustin](https://github.com/AgustinGDLV) | agustingdlv | Inactive | Gimmicks, Battle Engine, Tests, Items
| [tertu](https://github.com/tertu-m) | tertu | Inactive | Randomizer
## Attribution
This guide is based on the [contributing.md](https://contributing.md/generator)!

View File

@ -173,6 +173,21 @@ else
ROMTESTHYDRA := $(TOOLS_DIR)/mgba-rom-test-hydra/mgba-rom-test-hydra$(EXE)
endif
# Learnset helper is a Python script
LEARNSET_HELPERS_DIR := $(TOOLS_DIR)/learnset_helpers
LEARNSET_HELPERS_DATA_DIR := $(LEARNSET_HELPERS_DIR)/porymoves_files
LEARNSET_HELPERS_BUILD_DIR := $(LEARNSET_HELPERS_DIR)/build
ALL_LEARNABLES_JSON := $(LEARNSET_HELPERS_BUILD_DIR)/all_learnables.json
# wild_encounters.h is generated by a Python script
WILD_ENCOUNTERS_TOOL_DIR := $(TOOLS_DIR)/wild_encounters
AUTO_GEN_TARGETS += $(DATA_SRC_SUBDIR)/wild_encounters.h
$(DATA_SRC_SUBDIR)/wild_encounters.h: $(DATA_SRC_SUBDIR)/wild_encounters.json $(WILD_ENCOUNTERS_TOOL_DIR)/wild_encounters_to_header.py $(INCLUDE_DIRS)/config/overworld.h $(INCLUDE_DIRS)/config/dexnav.h
python3 $(WILD_ENCOUNTERS_TOOL_DIR)/wild_encounters_to_header.py > $@
$(C_BUILDDIR)/wild_encounter.o: c_dep += $(DATA_SRC_SUBDIR)/wild_encounters.h
PERL := perl
SHA1 := $(shell { command -v sha1sum || command -v shasum; } 2>/dev/null) -c
@ -347,6 +362,8 @@ generated: $(AUTO_GEN_TARGETS)
clean-generated:
@rm -f $(AUTO_GEN_TARGETS)
@echo "rm -f <AUTO_GEN_TARGETS>"
@rm -f $(ALL_LEARNABLES_JSON)
@echo "rm -f <ALL_LEARNABLES_JSON>"
COMPETITIVE_PARTY_SYNTAX := $(shell PATH="$(PATH)"; echo 'COMPETITIVE_PARTY_SYNTAX' | $(CPP) $(CPPFLAGS) -imacros include/gba/defines.h -imacros include/config/general.h | tail -n1)
ifeq ($(COMPETITIVE_PARTY_SYNTAX),1)
@ -386,6 +403,7 @@ ifneq ($(NODEP),1)
-include $(addprefix $(OBJ_DIR)/,$(C_SRCS:.c=.d))
endif
ifeq ($(TEST),1)
$(TEST_BUILDDIR)/%.o: $(TEST_SUBDIR)/%.c
@echo "$(CC1) <flags> -o $@ $<"
@$(CPP) $(CPPFLAGS) $< | $(PREPROC) -i $< charmap.txt | $(CC1) $(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $(AS) $(ASFLAGS) -o $@ -
@ -396,6 +414,7 @@ $(TEST_BUILDDIR)/%.d: $(TEST_SUBDIR)/%.c
ifneq ($(NODEP),1)
-include $(addprefix $(OBJ_DIR)/,$(TEST_SRCS:.c=.d))
endif
endif
$(ASM_BUILDDIR)/%.o: $(ASM_SUBDIR)/%.s
$(AS) $(ASFLAGS) -o $@ $<
@ -436,11 +455,16 @@ $(OBJ_DIR)/sym_common.ld: sym_common.txt $(C_OBJS) $(wildcard common_syms/*.txt)
$(OBJ_DIR)/sym_ewram.ld: sym_ewram.txt
$(RAMSCRGEN) ewram_data $< ENGLISH > $@
MOVES_JSON_DIR := $(TOOLS_DIR)/learnset_helpers/porymoves_files
TEACHABLE_DEPS := $(shell find data/ -type f -name '*.inc') $(INCLUDE_DIRS)/constants/tms_hms.h $(C_SUBDIR)/pokemon.c $(wildcard $(MOVES_JSON_DIR)/*.json)
TEACHABLE_DEPS := $(ALL_LEARNABLES_JSON) $(shell find data/ -type f -name '*.inc') $(INCLUDE_DIRS)/constants/tms_hms.h $(INCLUDE_DIRS)/config/pokemon.h $(C_SUBDIR)/pokemon.c
$(LEARNSET_HELPERS_BUILD_DIR):
@mkdir -p $@
$(ALL_LEARNABLES_JSON): $(wildcard $(LEARNSET_HELPERS_DATA_DIR)/*.json) | $(LEARNSET_HELPERS_BUILD_DIR)
python3 $(LEARNSET_HELPERS_DIR)/make_learnables.py $(LEARNSET_HELPERS_DATA_DIR) $@
$(DATA_SRC_SUBDIR)/pokemon/teachable_learnsets.h: $(TEACHABLE_DEPS)
python3 $(TOOLS_DIR)/learnset_helpers/teachable.py
python3 $(LEARNSET_HELPERS_DIR)/make_teachables.py $<
# Linker script
LD_SCRIPT := ld_script_modern.ld

View File

@ -12,7 +12,7 @@
# [Credits](CREDITS.md)
[![](https://img.shields.io/github/all-contributors/rh-hideout/pokeemerald-expansion/master)](CREDITS.md)
[![](https://img.shields.io/github/all-contributors/rh-hideout/pokeemerald-expansion/upcoming)](CREDITS.md)
If you use **`pokeemerald-expansion`**, please credit **RHH (Rom Hacking Hideout)**. Optionally, include the version number for clarity.

View File

@ -764,6 +764,10 @@
.4byte \failInstr
.endm
.macro removestockpilecounters
callnative BS_RemoveStockpileCounters
.endm
.macro setdrainedhp
.byte 0x88
.endm
@ -799,7 +803,8 @@
2:
.endm
.macro unused_0x8d
.macro trynonvolatilestatus
.byte 0x8d
.endm
.macro initmultihitstring
@ -829,7 +834,7 @@
.4byte \failInstr
.endm
.macro damagetohalftargethp
.macro unused_0x94
.byte 0x94
.endm
@ -877,11 +882,11 @@
.byte 0x9e
.endm
.macro dmgtolevel
.macro unused_0x9f
.byte 0x9f
.endm
.macro psywavedamageeffect
.macro unused_0xA0
.byte 0xa0
.endm
@ -1007,7 +1012,7 @@
.4byte \jumpInstr
.endm
.macro unused_bb
.macro tryrestorehpberry
.byte 0xbb
.endm
@ -1140,11 +1145,9 @@
.4byte \failInstr
.endm
.macro trywish turnNumber:req, failInstr:req, blockedInstr:req
.macro trywish failInstr:req
.byte 0xd4
.byte \turnNumber
.4byte \failInstr
.4byte \blockedInstr
.endm
.macro settoxicspikes failInstr:req
@ -1337,9 +1340,8 @@
.4byte \jumpInstr
.endm
.macro unused ptr:req
.macro setnonvolatilestatus
.byte 0xfd
.4byte \ptr
.endm
.macro tryworryseed failInstr:req
@ -1518,12 +1520,6 @@
.4byte \jumpInstr
.endm
.macro jumpifemergencyexited battler:req, jumpInstr:req
callnative BS_JumpIfEmergencyExited
.byte \battler
.4byte \jumpInstr
.endm
.macro jumpifelectricabilityaffected battler:req, ability:req, jumpInstr:req
callnative BS_JumpIfElectricAbilityAffected
.byte \battler
@ -1655,10 +1651,6 @@
callnative BS_TryTriggerStatusForm
.endm
.macro setdynamicmovecategory
callnative BS_SetDynamicMoveCategory
.endm
.macro tryupperhand failInstr:req
callnative BS_TryUpperHand
.4byte \failInstr
@ -1827,6 +1819,12 @@
.4byte \failInstr
.endm
.macro jumpifcangigantamax battler:req, jumpInstr:req
callnative BS_JumpIfCanGigantamax
.byte \battler
.4byte \jumpInstr
.endm
@ various command changed to more readable macros
.macro cancelmultiturnmoves battler:req
various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES
@ -1952,14 +1950,6 @@
various \battler, VARIOUS_RESTORE_PP
.endm
.macro tryactivatemoxie battler:req
various \battler, VARIOUS_TRY_ACTIVATE_MOXIE
.endm
.macro tryactivatebeastboost battler:req
various \battler, VARIOUS_TRY_ACTIVATE_BEAST_BOOST
.endm
.macro tryactivatereceiver battler:req
various \battler, VARIOUS_TRY_ACTIVATE_RECEIVER
.endm
@ -1968,10 +1958,6 @@
various BS_ATTACKER, VARIOUS_TRY_ACTIVATE_SOULHEART
.endm
.macro tryactivatefellstinger battler:req
various \battler, VARIOUS_TRY_ACTIVATE_FELL_STINGER
.endm
.macro playmoveanimation battler:req, move:req
various \battler, VARIOUS_PLAY_MOVE_ANIMATION
.2byte \move
@ -2045,10 +2031,6 @@
.4byte \jumpInstr
.endm
.macro setargtobattledamage
various BS_ATTACKER, VARIOUS_SET_ARG_TO_BATTLE_DAMAGE
.endm
.macro tryautotomize battler:req, failInstr:req
various \battler, VARIOUS_TRY_AUTOTOMIZE
.4byte \failInstr
@ -2187,18 +2169,6 @@
.4byte \jumpInstr
.endm
.macro trypoisontype attacker:req, target:req, failInstr:req
various \attacker, VARIOUS_POISON_TYPE_IMMUNITY
.byte \target
.4byte \failInstr
.endm
.macro tryparalyzetype attacker:req, target:req, failInstr:req
various \attacker, VARIOUS_PARALYZE_TYPE_IMMUNITY
.byte \target
.4byte \failInstr
.endm
.macro trysetfairylock failInstr:req
various BS_ATTACKER, VARIOUS_TRY_FAIRY_LOCK
.4byte \failInstr
@ -2243,10 +2213,6 @@
.4byte \jumpInstr
.endm
.macro tryactivategrimneigh, battler:req
various \battler, VARIOUS_TRY_ACTIVATE_GRIM_NEIGH
.endm
.macro consumeberry battler:req, fromBattler:req
various \battler, VARIOUS_CONSUME_BERRY
.byte \fromBattler
@ -2307,10 +2273,6 @@
.4byte \jumpInstr
.endm
.macro tryactivatebattlebond battler:req
various \battler, VARIOUS_TRY_ACTIVATE_BATTLE_BOND
.endm
.macro jumpifcantreverttoprimal jumpInstr:req
various BS_ATTACKER, VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL
.4byte \jumpInstr
@ -2360,9 +2322,10 @@
.4byte \jumpInstr
.endm
.macro jumpiflastuseditemholdeffect battler:req, holdEffect:req, jumpInstr:req
various \battler, VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT
.macro jumpiflastuseditemholdeffect holdEffect:req, secondaryId:req, jumpInstr:req
callnative BS_JumpIfLastUsedItemHoldEffect
.byte \holdEffect
.2byte \secondaryId
.4byte \jumpInstr
.endm
@ -2595,3 +2558,8 @@
printstring STRINGID_EMPTYSTRING3
waitmessage 1
.endm
.macro jumpifnowhiteout jumpInstr:req
callnative BS_JumpIfNoWhiteOut
.4byte \jumpInstr
.endm

View File

@ -341,6 +341,12 @@
.byte SCR_OP_GETTIME
.endm
@ Sets the values of variable VAR_0x8000 to the time of day according to those found in rtc.h.
@ 0 = MORNING, 1 = DAY, 2 = EVENING, 3 = NIGHT
.macro gettimeofday
callnative ScrCmd_gettimeofday, requests_effects=1
.endm
@ Plays the specified sound. Only one sound may play at a time, with newer ones interrupting older ones.
.macro playse song:req
.byte SCR_OP_PLAYSE
@ -1793,11 +1799,14 @@
.4byte \text
.endm
@ Equivalent to fadescreen but copies gPlttBufferUnfaded to an allocated buffer on the fade out
@ and the reverse on the fade in, in effect saving gPlttBufferUnfaded to restore it.
.macro fadescreenswapbuffers mode:req
@ Equivalent to fadescreen but uses a hardware fade and darken/lighten blend modes,
@ to avoid modifying palettes at all.
@ Useful for fade-out/fade-in without leaving the overworld or entering a new scene.
@ If nowait set, doesn't wait for the fade to complete
.macro fadescreenswapbuffers mode:req, nowait=0
.byte SCR_OP_FADESCREENSWAPBUFFERS
.byte \mode
.byte \nowait
.endm
@ Buffers the specified trainer's class name to the given string var.
@ -2302,7 +2311,11 @@
callnative ScriptSetDoubleBattleFlag, requests_effects=1
.endm
@ When OW_USE_FAKE_RTC and OW_FLAG_PAUSE_TIME is assigned, this macro will stop the flow of time.
@ ============================ @
@ FAKE RTC MACROS
@ Will only function if OW_USE_FAKE_RTC is true. If it has any additional requirements, it will be listed accordingly.
@ When OW_USE_FAKE_RTC is true and OW_FLAG_PAUSE_TIME is assigned, this macro will stop the flow of time.
.macro pausefakertc
callnative Script_PauseFakeRtc, requests_effects=1
.endm
@ -2317,6 +2330,46 @@
callnative Script_ToggleFakeRtc, requests_effects=1
.endm
@ When OW_USE_FAKE_RTC is true, adds a specified amount of time.
.macro addtime days:req, hours:req, minutes:req
callnative ScrCmd_addtime, requests_effects=1
.4byte \days
.4byte \hours
.4byte \minutes
.endm
@ When OW_USE_FAKE_RTC is true, adds a specified number of days to the time.
.macro adddays days:req
callnative ScrCmd_adddays, requests_effects=1
.4byte \days
.endm
@ When OW_USE_FAKE_RTC is true, adds a specified number of days, hours, and minutes to the time.
.macro addhours hours:req
callnative ScrCmd_addhours, requests_effects=1
.4byte \hours
.endm
@ When OW_USE_FAKE_RTC is true, adds a specified number of days, hours, and minutes to the time.
.macro addminutes minutes:req
callnative ScrCmd_addminutes, requests_effects=1
.4byte \minutes
.endm
@ Forwards the time to a specified hour and minute.
@ This causes the time to go to the next day if the time has already been past.
.macro fwdtime hours:req, minutes:req
callnative ScrCmd_fwdtime, requests_effects=1
.4byte \hours
.4byte \minutes
.endm
@ Forwards the time to a specified day of the week. Uses a 0-index starting from Sunday.
.macro fwdweekday weekday:req
callnative ScrCmd_fwdweekday, requests_effects=1
.4byte \weekday
.endm
@ ============================ @
@ ITEM DESCRIPTION HEADER MACROS
@ Used with OW_SHOW_ITEM_DESCRIPTIONS config
@ -2447,7 +2500,7 @@
callnative Script_SetDifficulty, requests_effects=1
.byte \difficulty
.endm
.macro forcesave
callnative Script_ForceSaveGame
waitstate
@ -2513,3 +2566,76 @@
compare \a, \b
cant_see_if 5
.endm
@ Follower NPCs
@ Sets an NPC up to follow the player.
@ Follower flags are defined in include/constants/follower_npc.h
@ If you want to specify a battle partner without specifying a custom script, you can set the script parameter to 0.
.macro setfollowernpc localId:req, flags:req, script=0, battlePartner=0
.if FNPC_ENABLE_NPC_FOLLOWERS
checkfollowernpc
compare VAR_RESULT, FALSE
goto_if_ne 1f
hidefollower
waitmovement OBJ_EVENT_ID_FOLLOWER
callnative ScriptSetFollowerNPC
.if \script == 0
.set setScript, FALSE
.else
.set setScript, TRUE
.endif
.byte \localId
.2byte \flags
.byte setScript
.2byte \battlePartner
.4byte \script
updatefollowingmon
1:
.else
.error "setfollowernpc unavailable with FNPC_ENABLE_NPC_FOLLOWERS defined as FALSE"
.endif
.endm
@ Remove the follower NPC (assumes there will only ever be one).
.macro destroyfollowernpc
.if FNPC_ENABLE_NPC_FOLLOWERS
callnative ScriptDestroyFollowerNPC
.else
.error "destroyfollowernpc unavailable with FNPC_ENABLE_NPC_FOLLOWERS defined as FALSE"
.endif
.endm
@ Makes the player and follower NPC face one another.
.macro facefollowernpc
callnative ScriptFaceFollowerNPC
.endm
@ Makes the follower NPC walk into the player and get hidden.
@ Optionally, you can set the walk speed for the movement:
@ 0 = Slow
@ 1 = Normal (default)
@ 2 = Fast
@ 3 = Faster
.macro hidefollowernpc speed=1
callnative ScriptHideNPCFollower
.byte \speed
waitmovement OBJ_EVENT_ID_NPC_FOLLOWER
callnative HideNPCFollower
.endm
@ Checks if you have a follower NPC. Returns the result to VAR_RESULT.
.macro checkfollowernpc
callnative ScriptCheckFollowerNPC
.endm
@ Updates Pokemon follower.
.macro updatefollowingmon
callnative ScriptUpdateFollowingMon
.endm
@ Changes the battle partner of the existing follower NPC.
.macro changefollowerbattler battlePartner:req
callnative ScriptChangeFollowerNPCBattlePartner
.2byte \battlePartner
.endm

View File

@ -1,3 +1,4 @@
#include "constants/field_weather.h"
@ The first .byte argument of each macro below is an index into gFieldEffectScriptFuncs
.macro field_eff_loadtiles address:req
@ -5,9 +6,10 @@
.4byte \address
.endm
.macro field_eff_loadfadedpal address:req
.macro field_eff_loadfadedpal address:req, color_map_type=COLOR_MAP_DARK_CONTRAST
.byte 1
.4byte \address
.byte \color_map_type
.endm
.macro field_eff_loadpal address:req
@ -24,10 +26,11 @@
.byte 4
.endm
.macro field_eff_loadgfx_callnative tiles_address:req, palette_address:req, function_address:req
.macro field_eff_loadgfx_callnative tiles_address:req, palette_address:req, function_address:req, color_map_type=COLOR_MAP_DARK_CONTRAST
.byte 5
.4byte \tiles_address
.4byte \palette_address
.byte \color_map_type
.4byte \function_address
.endm
@ -37,8 +40,9 @@
.4byte \function_address
.endm
.macro field_eff_loadfadedpal_callnative palette_address:req, function_address:req
.macro field_eff_loadfadedpal_callnative palette_address:req, function_address:req, color_map_type=COLOR_MAP_DARK_CONTRAST
.byte 7
.4byte \palette_address
.byte \color_map_type
.4byte \function_address
.endm

View File

@ -6,12 +6,15 @@ MID_ASM_DIR := $(MID_SUBDIR)
CRY_BIN_DIR := $(CRY_SUBDIR)
SOUND_BIN_DIR := sound
# Needs to recompile for B_NUM_LOW_HEALTH_BEEPS in battle.h
EXPANSION_BATTLE_CONFIG := include/config/battle.h
SPECIAL_OUTDIRS := $(MID_ASM_DIR) $(CRY_BIN_DIR)
SPECIAL_OUTDIRS += $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/direct_sound_samples/phonemes $(SOUND_BIN_DIR)/direct_sound_samples/cries
$(shell mkdir -p $(SPECIAL_OUTDIRS) )
# Assembly song compilation
$(SONG_BUILDDIR)/%.o: $(SONG_SUBDIR)/%.s
$(SONG_BUILDDIR)/%.o: $(SONG_SUBDIR)/%.s $(EXPANSION_BATTLE_CONFIG)
$(AS) $(ASFLAGS) -I sound -o $@ $<
$(MID_BUILDDIR)/%.o: $(MID_ASM_DIR)/%.s
$(AS) $(ASFLAGS) -I sound -o $@ $<
@ -34,7 +37,7 @@ MID_CFG_PATH := $(MID_SUBDIR)/midi.cfg
# $1: Source path no extension, $2 Options
define MID_RULE
$(MID_ASM_DIR)/$1.s: $(MID_SUBDIR)/$1.mid $(MID_CFG_PATH)
$(MID_ASM_DIR)/$1.s: $(MID_SUBDIR)/$1.mid $(MID_CFG_PATH) $(EXPANSION_BATTLE_CONFIG)
$(MID) $$< $$@ $2
endef
# source path, remaining text (options)

View File

@ -1064,6 +1064,7 @@ ROUND_RIGHT_PAREN = F9 14
CIRCLE_DOT = F9 15
TRIANGLE = F9 16
BIG_MULT_X = F9 17
CIRCLE_HOLLOW = F9 18
EMOJI_UNDERSCORE = F9 D0
EMOJI_PIPE = F9 D1

File diff suppressed because it is too large Load Diff

View File

@ -272,7 +272,11 @@ BattleScript_EffectChillyReception::
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, B_WEATHER_RAIN_PRIMAL, BattleScript_EffectChillyReceptionBlockedByPrimalRain
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, B_WEATHER_STRONG_WINDS, BattleScript_EffectChillyReceptionBlockedByStrongWinds
call BattleScript_EffectChillyReceptionPlayAnimation
#if B_PREFERRED_ICE_WEATHER == B_ICE_WEATHER_HAIL
setfieldweather BATTLE_WEATHER_HAIL
#else
setfieldweather BATTLE_WEATHER_SNOW
#endif
call BattleScript_MoveWeatherChangeRet
goto BattleScript_MoveSwitch
BattleScript_EffectChillyReceptionPlayAnimation:
@ -304,13 +308,17 @@ BattleScript_CheckPrimalWeather:
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, B_WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOn
return
BattleScript_MoveSwitchPursuit:
BattleScript_MoveSwitchPursuitEnd:
call BattleScript_MoveSwitchPursuitRet
end
BattleScript_MoveSwitchPursuitRet:
jumpifbattletype BATTLE_TYPE_ARENA, BattleScript_MoveSwitchEnd
jumpifcantswitch SWITCH_IGNORE_ESCAPE_PREVENTION | BS_ATTACKER, BattleScript_MoveSwitchEnd
printstring STRINGID_PKMNWENTBACK
waitmessage B_WAIT_TIME_SHORT
jumpifnopursuitswitchdmg BattleScript_MoveSwitchOpenPartyScreen
end
return
BattleScript_MoveSwitch:
jumpifbattletype BATTLE_TYPE_ARENA, BattleScript_MoveSwitchEnd
@ -410,12 +418,12 @@ BattleScript_MoveEffectSaltCure::
return
BattleScript_SaltCureExtraDamage::
playanimation BS_TARGET, B_ANIM_SALT_CURE_DAMAGE, NULL
playanimation BS_ATTACKER, B_ANIM_SALT_CURE_DAMAGE, NULL
waitanimation
call BattleScript_HurtTarget_NoString
printstring STRINGID_TARGETISHURTBYSALTCURE
waitmessage B_WAIT_TIME_LONG
tryfaintmon BS_TARGET
tryfaintmon BS_ATTACKER
end2
BattleScript_HurtTarget_NoString:
@ -766,13 +774,13 @@ BattleScript_EffectFling::
waitmessage B_WAIT_TIME_MED
jumpiflastuseditemberry BattleScript_EffectFlingConsumeBerry
jumpifability BS_TARGET, ABILITY_SHIELD_DUST, BattleScript_FlingBlockedByShieldDust
jumpiflastuseditemholdeffect BS_ATTACKER, HOLD_EFFECT_FLAME_ORB, BattleScript_FlingFlameOrb
jumpiflastuseditemholdeffect BS_ATTACKER, HOLD_EFFECT_FLINCH, BattleScript_FlingFlinch
jumpiflastuseditemholdeffect BS_ATTACKER, HOLD_EFFECT_LIGHT_BALL, BattleScript_FlingLightBall
jumpiflastuseditemholdeffect BS_ATTACKER, HOLD_EFFECT_MENTAL_HERB, BattleScript_FlingMentalHerb
jumpiflastuseditemholdeffect BS_ATTACKER, HOLD_EFFECT_POISON_POWER, BattleScript_FlingPoisonBarb
jumpiflastuseditemholdeffect BS_ATTACKER, HOLD_EFFECT_TOXIC_ORB, BattleScript_FlingToxicOrb
jumpiflastuseditemholdeffect BS_ATTACKER, HOLD_EFFECT_RESTORE_STATS, BattleScript_FlingWhiteHerb
jumpiflastuseditemholdeffect HOLD_EFFECT_FLAME_ORB, 0, BattleScript_FlingFlameOrb
jumpiflastuseditemholdeffect HOLD_EFFECT_FLINCH, 0, BattleScript_FlingFlinch
jumpiflastuseditemholdeffect HOLD_EFFECT_LIGHT_BALL, 0, BattleScript_FlingLightBall
jumpiflastuseditemholdeffect HOLD_EFFECT_MENTAL_HERB, 0, BattleScript_FlingMentalHerb
jumpiflastuseditemholdeffect HOLD_EFFECT_TYPE_POWER, TYPE_POISON, BattleScript_FlingPoisonBarb
jumpiflastuseditemholdeffect HOLD_EFFECT_TOXIC_ORB, 0, BattleScript_FlingToxicOrb
jumpiflastuseditemholdeffect HOLD_EFFECT_WHITE_HERB, 0, BattleScript_FlingWhiteHerb
goto BattleScript_FlingEnd
BattleScript_EffectFlingConsumeBerry:
savebattleritem BS_TARGET
@ -836,10 +844,6 @@ BattleScript_FlingMissed:
ppreduce
goto BattleScript_MoveMissedPause
BattleScript_EffectDynamicCategory::
setdynamicmovecategory
goto BattleScript_EffectHit
BattleScript_EffectAuraWheel:: @ Aura Wheel can only be used by Morpeko
jumpifspecies BS_ATTACKER, SPECIES_MORPEKO_FULL_BELLY, BattleScript_EffectHit
jumpifspecies BS_ATTACKER, SPECIES_MORPEKO_HANGRY, BattleScript_EffectHit
@ -1344,7 +1348,7 @@ BattleScript_EffectPartingShotTrySpAtk:
waitmessage B_WAIT_TIME_LONG
BattleScript_EffectPartingShotSwitch:
moveendall
goto BattleScript_MoveSwitchPursuit
goto BattleScript_MoveSwitchPursuitEnd
BattleScript_EffectPowder::
attackcanceler
@ -2768,21 +2772,12 @@ BattleScript_EffectHealBlock::
goto BattleScript_MoveEnd
BattleScript_EffectHitEscape::
call BattleScript_EffectHit_Ret
jumpifmovehadnoeffect BattleScript_MoveEnd
tryfaintmon BS_TARGET
moveendto MOVEEND_ATTACKER_VISIBLE
moveendfrom MOVEEND_TARGET_VISIBLE
jumpifbattleend BattleScript_HitEscapeEnd
jumpifbyte CMP_NOT_EQUAL, gBattleOutcome, 0, BattleScript_HitEscapeEnd
jumpifemergencyexited BS_TARGET, BattleScript_HitEscapeEnd
jumpiffainted BS_TARGET, FALSE, BattleScript_HitEscapeSwitch
setbyte sGIVEEXP_STATE, 0
getexp BS_TARGET
BattleScript_HitEscapeSwitch:
goto BattleScript_MoveSwitchPursuit
BattleScript_HitEscapeEnd:
end
call BattleScript_MoveSwitchPursuitRet
return
BattleScript_EffectPlaceholder::
attackcanceler
@ -2868,34 +2863,9 @@ BattleScript_MoveMissed::
BattleScript_EffectDarkVoid::
.if B_DARK_VOID_FAIL >= GEN_7
jumpifspecies BS_ATTACKER, SPECIES_DARKRAI, BattleScript_EffectSleep
jumpifspecies BS_ATTACKER, SPECIES_DARKRAI, BattleScript_EffectNonVolatileStatus
goto BattleScript_PokemonCantUseTheMove
.endif
BattleScript_EffectSleep::
attackcanceler
attackstring
ppreduce
jumpifsubstituteblocks BattleScript_ButItFailed
jumpifstatus BS_TARGET, STATUS1_SLEEP, BattleScript_AlreadyAsleep
jumpifuproarwakes BattleScript_CantMakeAsleep
jumpifability BS_TARGET, ABILITY_INSOMNIA, BattleScript_InsomniaProtects
jumpifability BS_TARGET, ABILITY_VITAL_SPIRIT, BattleScript_InsomniaProtects
jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect
jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect
jumpifflowerveil BattleScript_FlowerVeilProtects
jumpifability BS_TARGET_SIDE, ABILITY_SWEET_VEIL, BattleScript_SweetVeilProtects
jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifsleepclause BattleScript_SleepClauseBlocked
jumpifterrainaffected BS_TARGET, STATUS_FIELD_ELECTRIC_TERRAIN, BattleScript_ElectricTerrainPrevents
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected
attackanimation
waitanimation
seteffectprimary MOVE_EFFECT_SLEEP
goto BattleScript_MoveEnd
BattleScript_TerrainPreventsEnd2::
pause B_WAIT_TIME_SHORT
@ -2924,7 +2894,7 @@ BattleScript_FlowerVeilProtectsRet::
waitmessage B_WAIT_TIME_LONG
return
BattleScript_FlowerVeilProtects:
BattleScript_FlowerVeilProtects::
call BattleScript_FlowerVeilProtectsRet
setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
@ -2953,15 +2923,11 @@ BattleScript_AromaVeilProtects:
setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_PastelVeilProtectsRet::
BattleScript_PastelVeilProtects:
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
printstring STRINGID_PASTELVEILPROTECTED
waitmessage B_WAIT_TIME_LONG
return
BattleScript_PastelVeilProtects:
call BattleScript_PastelVeilProtectsRet
setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
@ -2972,7 +2938,7 @@ BattleScript_AbilityProtectsDoesntAffectRet::
waitmessage B_WAIT_TIME_LONG
return
BattleScript_AbilityProtectsDoesntAffect:
BattleScript_AbilityProtectsDoesntAffect::
call BattleScript_AbilityProtectsDoesntAffectRet
setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
@ -3320,31 +3286,6 @@ BattleScript_RestoreHp:
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectToxic::
attackcanceler
attackstring
ppreduce
jumpifability BS_TARGET, ABILITY_IMMUNITY, BattleScript_ImmunityProtected
jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect
jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect
jumpifability BS_TARGET_SIDE, ABILITY_PASTEL_VEIL, BattleScript_PastelVeilProtects
jumpifflowerveil BattleScript_FlowerVeilProtects
jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifsubstituteblocks BattleScript_ButItFailed
jumpifstatus BS_TARGET, STATUS1_POISON | STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
trypoisontype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected
attackanimation
waitanimation
seteffectprimary MOVE_EFFECT_TOXIC
resultmessage
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_AlreadyPoisoned::
setalreadystatusedmoveattempt BS_ATTACKER
pause B_WAIT_TIME_LONG
@ -3353,10 +3294,10 @@ BattleScript_AlreadyPoisoned::
goto BattleScript_MoveEnd
BattleScript_ImmunityProtected::
copybyte gEffectBattler, gBattlerTarget
call BattleScript_AbilityPopUp
setbyte cMULTISTRING_CHOOSER, B_MSG_ABILITY_PREVENTS_MOVE_STATUS
call BattleScript_PSNPrevention
pause B_WAIT_TIME_SHORT
printfromtable gStatusPreventionStringIds
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectAuroraVeil::
@ -3429,16 +3370,6 @@ BattleScript_KOFail::
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectSuperFang::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
typecalc
clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
damagetohalftargethp
goto BattleScript_HitFromAtkAnimation
BattleScript_RecoilIfMiss::
printstring STRINGID_PKMNCRASHED
waitmessage B_WAIT_TIME_LONG
@ -3586,78 +3517,18 @@ BattleScript_EffectAuroraVeilSuccess::
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectPoison::
attackcanceler
attackstring
ppreduce
jumpifability BS_TARGET, ABILITY_IMMUNITY, BattleScript_ImmunityProtected
jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect
jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect
jumpifability BS_TARGET_SIDE, ABILITY_PASTEL_VEIL, BattleScript_PastelVeilProtects
jumpifflowerveil BattleScript_FlowerVeilProtects
jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifsubstituteblocks BattleScript_ButItFailed
jumpifstatus BS_TARGET, STATUS1_POISON, BattleScript_AlreadyPoisoned
jumpifstatus BS_TARGET, STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned
trypoisontype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected
attackanimation
waitanimation
seteffectprimary MOVE_EFFECT_POISON
resultmessage
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectParalyze::
attackcanceler
attackstring
ppreduce
jumpifability BS_TARGET, ABILITY_LIMBER, BattleScript_LimberProtected
jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect
jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect
jumpifflowerveil BattleScript_FlowerVeilProtects
jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifsubstituteblocks BattleScript_ButItFailed
typecalc
jumpifmovehadnoeffect BattleScript_ButItFailed
jumpifstatus BS_TARGET, STATUS1_PARALYSIS, BattleScript_AlreadyParalyzed
jumpifelectricabilityaffected BS_TARGET, ABILITY_VOLT_ABSORB, BattleScript_VoltAbsorbHeal
clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
tryparalyzetype BS_ATTACKER, BS_TARGET, BattleScript_NotAffected
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected
attackanimation
waitanimation
seteffectprimary MOVE_EFFECT_PARALYSIS
resultmessage
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_VoltAbsorbHeal:
copybyte gBattlerAbility, gBattlerTarget
tryhealquarterhealth BS_TARGET BattleScript_MonMadeMoveUseless @ Check if max hp
goto BattleScript_MoveHPDrain
BattleScript_AlreadyParalyzed:
BattleScript_AlreadyParalyzed::
setalreadystatusedmoveattempt BS_ATTACKER
pause B_WAIT_TIME_SHORT
printstring STRINGID_PKMNISALREADYPARALYZED
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_LimberProtected::
copybyte gEffectBattler, gBattlerTarget
setbyte cMULTISTRING_CHOOSER, B_MSG_ABILITY_PREVENTS_MOVE_STATUS
call BattleScript_PRLZPrevention
goto BattleScript_MoveEnd
BattleScript_PowerHerbActivation:
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT
printstring STRINGID_POWERHERB
@ -3846,7 +3717,7 @@ BattleScript_EffectHoldHands::
attackcanceler
attackstring
ppreduce
jumpifsideaffecting BS_TARGET, SIDE_STATUS_CRAFTY_SHIELD, BattleScript_ButItFailed
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
jumpifbyteequal gBattlerTarget, gBattlerAttacker, BattleScript_ButItFailed
attackanimation
waitanimation
@ -3884,28 +3755,6 @@ BattleScript_EffectDisable::
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectLevelDamage::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
typecalc
clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
dmgtolevel
adjustdamage
goto BattleScript_HitFromAtkAnimation
BattleScript_EffectPsywave::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
typecalc
clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
psywavedamageeffect
adjustdamage
goto BattleScript_HitFromAtkAnimation
BattleScript_EffectCounter::
attackcanceler
counterdamagecalculator BattleScript_FailedFromAtkString
@ -4393,17 +4242,6 @@ BattleScript_EffectBatonPass::
switchineffects BS_ATTACKER
goto BattleScript_MoveEnd
BattleScript_EffectFixedDamageArg::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
typecalc
clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
setargtobattledamage
adjustdamage
goto BattleScript_HitFromAtkAnimation
BattleScript_EffectMorningSun::
BattleScript_EffectSynthesis::
BattleScript_EffectMoonlight::
@ -4760,7 +4598,10 @@ BattleScript_EffectSpitUp::
damagecalc
adjustdamage
stockpiletobasedamage BattleScript_SpitUpFail
goto BattleScript_HitFromAtkAnimation
call BattleScript_Hit_RetFromAtkAnimation
tryfaintmon BS_TARGET
removestockpilecounters
goto BattleScript_SpitUpEnd
BattleScript_SpitUpFail::
checkparentalbondcounter 2, BattleScript_SpitUpEnd
pause B_WAIT_TIME_SHORT
@ -4783,7 +4624,16 @@ BattleScript_EffectSwallow::
attackstring
ppreduce
stockpiletohpheal BattleScript_SwallowFail
goto BattleScript_PresentHealTarget
attackanimation
waitanimation
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
healthbarupdate BS_TARGET
datahpupdate BS_TARGET
printstring STRINGID_PKMNREGAINEDHEALTH
waitmessage B_WAIT_TIME_LONG
removestockpilecounters
goto BattleScript_MoveEnd
BattleScript_SwallowFail::
pause B_WAIT_TIME_SHORT
@ -4834,35 +4684,17 @@ BattleScript_FlatterTryConfuse::
seteffectprimary MOVE_EFFECT_CONFUSION
goto BattleScript_MoveEnd
BattleScript_EffectWillOWisp::
BattleScript_EffectNonVolatileStatus::
attackcanceler
attackstring
ppreduce
jumpifsubstituteblocks BattleScript_ButItFailed
jumpifstatus BS_TARGET, STATUS1_BURN, BattleScript_AlreadyBurned
jumpiftype BS_TARGET, TYPE_FIRE, BattleScript_NotAffected
jumpifability BS_TARGET, ABILITY_WATER_VEIL, BattleScript_WaterVeilPrevents
jumpifability BS_TARGET, ABILITY_WATER_BUBBLE, BattleScript_WaterVeilPrevents
jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect
jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect
jumpifability BS_TARGET, ABILITY_THERMAL_EXCHANGE, BattleScript_AbilityProtectsDoesntAffect
jumpifflowerveil BattleScript_FlowerVeilProtects
jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
trynonvolatilestatus
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected
attackanimation
waitanimation
seteffectprimary MOVE_EFFECT_BURN
goto BattleScript_MoveEnd
BattleScript_WaterVeilPrevents::
call BattleScript_AbilityPopUp
copybyte gEffectBattler, gBattlerTarget
setbyte cMULTISTRING_CHOOSER, B_MSG_ABILITY_PREVENTS_MOVE_STATUS
call BattleScript_BRNPrevention
setnonvolatilestatus
resultmessage
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_AlreadyBurned::
@ -5033,7 +4865,7 @@ BattleScript_EffectWish::
attackcanceler
attackstring
ppreduce
trywish 0, BattleScript_ButItFailed, BattleScript_ButItFailed
trywish BattleScript_ButItFailed
attackanimation
waitanimation
goto BattleScript_MoveEnd
@ -5116,18 +4948,8 @@ BattleScript_EffectYawn::
attackcanceler
attackstring
ppreduce
jumpifability BS_TARGET, ABILITY_VITAL_SPIRIT, BattleScript_PrintBattlerAbilityMadeIneffective
jumpifability BS_TARGET, ABILITY_INSOMNIA, BattleScript_PrintBattlerAbilityMadeIneffective
jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_PrintBattlerAbilityMadeIneffective
jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect
jumpifflowerveil BattleScript_FlowerVeilProtects
jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifsleepclause BattleScript_SleepClauseBlocked
jumpifsubstituteblocks BattleScript_ButItFailed
jumpifsafeguard BattleScript_SafeguardProtected
trynonvolatilestatus
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
jumpifuproarwakes BattleScript_ButItFailed
setyawn BattleScript_ButItFailed
attackanimation
waitanimation
@ -5135,8 +4957,7 @@ BattleScript_EffectYawnSuccess::
printstring STRINGID_PKMNWASMADEDROWSY
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_PrintBattlerAbilityMadeIneffective::
copybyte sBATTLER, gBattlerAbility
BattleScript_PrintAbilityMadeIneffective::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
@ -5424,13 +5245,8 @@ BattleScript_FaintTarget::
dofaintanimation BS_TARGET
printstring STRINGID_TARGETFAINTED
cleareffectsonfaint BS_TARGET
tryactivatefellstinger BS_ATTACKER
tryactivatesoulheart
tryactivatereceiver BS_TARGET
tryactivatemoxie BS_ATTACKER @ and chilling neigh, as one ice rider
tryactivatebeastboost BS_ATTACKER
tryactivategrimneigh BS_ATTACKER @ and as one shadow rider
tryactivatebattlebond BS_ATTACKER
trytrainerslidefirstdownmsg BS_TARGET
return
@ -5578,19 +5394,19 @@ BattleScript_LocalBattleLost::
jumpifbattletype BATTLE_TYPE_TRAINER_HILL, BattleScript_LocalBattleLostPrintTrainersWinText
jumpifbattletype BATTLE_TYPE_EREADER_TRAINER, BattleScript_LocalBattleLostEnd
jumpifhalfword CMP_EQUAL, gTrainerBattleParameter + 2, TRAINER_SECRET_BASE, BattleScript_LocalBattleLostEnd
jumpifnowhiteout BattleScript_LocalBattleLostEnd_
BattleScript_LocalBattleLostPrintWhiteOut::
getmoneyreward
.if B_WHITEOUT_MONEY >= GEN_4
jumpifbattletype BATTLE_TYPE_TRAINER, BattleScript_LocalBattleLostEnd
printstring STRINGID_PLAYERWHITEOUT
waitmessage B_WAIT_TIME_LONG
getmoneyreward
printstring STRINGID_PLAYERWHITEOUT2
waitmessage B_WAIT_TIME_LONG
end2
BattleScript_LocalBattleLostEnd::
printstring STRINGID_PLAYERLOSTTOENEMYTRAINER
waitmessage B_WAIT_TIME_LONG
getmoneyreward
printstring STRINGID_PLAYERPAIDPRIZEMONEY
waitmessage B_WAIT_TIME_LONG
end2
@ -5820,7 +5636,7 @@ BattleScript_DamagingWeather::
printfromtable gSandStormHailDmgStringIds
waitmessage B_WAIT_TIME_LONG
effectivenesssound
hitanimation BS_SCRIPTING
hitanimation BS_ATTACKER
goto BattleScript_DoTurnDmg
BattleScript_FogEnded_Ret::
@ -5830,13 +5646,13 @@ BattleScript_FogEnded_Ret::
return
BattleScript_IceBodyHeal::
call BattleScript_AbilityPopUpScripting
playanimation BS_SCRIPTING, B_ANIM_SIMPLE_HEAL
healthbarupdate BS_SCRIPTING
datahpupdate BS_SCRIPTING
call BattleScript_AbilityPopUp
playanimation BS_ATTACKER, B_ANIM_SIMPLE_HEAL
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
printstring STRINGID_ICEBODYHPGAIN
waitmessage B_WAIT_TIME_LONG
end2
end3
BattleScript_OverworldStatusStarts::
printfromtable gStartingStatusStringIds
@ -5897,12 +5713,14 @@ BattleScript_WonderRoomEnds::
BattleScript_MagicRoomEnds::
printstring STRINGID_MAGICROOMENDS
waitmessage B_WAIT_TIME_LONG
setbyte gBattlerTarget, 0
BattleScript_MagicRoomHealingItemsLoop:
copyarraywithindex gBattlerAttacker, gBattlerByTurnOrder, gBattlerTarget, 1
tryrestorehpberry
addbyte gBattlerTarget, 1
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_MagicRoomHealingItemsLoop
end2
BattleScript_GrassyTerrainEnds::
call BattleScript_GrassyTerrainHeals_Ret
goto BattleScript_TerrainEnds
BattleScript_TerrainEnds_Ret::
printfromtable gTerrainStringIds
waitmessage B_WAIT_TIME_LONG
@ -6675,7 +6493,6 @@ BattleScript_SelectingNotAllowedCurrentMoveInPalace::
goto BattleScript_SelectingUnusableMoveInPalace
BattleScript_WishComesTrue::
trywish 1, BattleScript_WishButFullHp, BattleScript_WishButHealBlocked
playanimation BS_TARGET, B_ANIM_WISH_HEAL
printstring STRINGID_PKMNWISHCAMETRUE
waitmessage B_WAIT_TIME_LONG
@ -6918,6 +6735,21 @@ BattleScript_PrimalReversion::
switchinabilities BS_SCRIPTING
end3
BattleScript_PowerConstruct::
flushtextbox
printstring STRINGID_POWERCONSTRUCTPRESENCEOFMANY
waitmessage B_WAIT_TIME_SHORT
copybyte gBattlerAbility, gBattlerAttacker
call BattleScript_AbilityPopUp
handleformchange BS_ATTACKER, 0
handleformchange BS_ATTACKER, 1
playanimation BS_ATTACKER, B_ANIM_POWER_CONSTRUCT
waitanimation
handleformchange BS_ATTACKER, 2
printstring STRINGID_POWERCONSTRUCTTRANSFORM
waitmessage B_WAIT_TIME_SHORT
end3
BattleScript_UltraBurst::
flushtextbox
trytrainerslidezmovemsg
@ -7002,7 +6834,7 @@ BattleScript_CudChewActivates::
pause B_WAIT_TIME_SHORTEST
call BattleScript_AbilityPopUp
setbyte sBERRY_OVERRIDE, 1 @ override the requirements for eating berries
consumeberry BS_SCRIPTING, FALSE
consumeberry BS_ATTACKER, FALSE
setbyte sBERRY_OVERRIDE, 0
end3
@ -7056,6 +6888,14 @@ BattleScript_BattlerFormChangeWithStringEnd3::
waitmessage B_WAIT_TIME_LONG
end3
BattleScript_IllusionOffAndTerastallization::
call BattleScript_IllusionOff
goto BattleScript_Terastallization
BattleScript_IllusionOffEnd3::
call BattleScript_IllusionOff
end3
BattleScript_IllusionOff::
spriteignore0hp TRUE
playanimation BS_SCRIPTING, B_ANIM_ILLUSION_OFF
@ -7153,6 +6993,7 @@ BattleScript_DoTurnDmg:
datahpupdate BS_ATTACKER
tryfaintmon BS_ATTACKER
checkteamslost BattleScript_DoTurnDmgEnd
tryrestorehpberry
BattleScript_DoTurnDmgEnd:
end2
@ -7400,6 +7241,7 @@ BattleScript_YawnEnd:
BattleScript_EmbargoEndTurn::
printstring STRINGID_EMBARGOENDS
waitmessage B_WAIT_TIME_LONG
tryrestorehpberry
end2
BattleScript_TelekinesisEndTurn::
@ -7521,9 +7363,9 @@ BattleScript_AbilityRaisesDefenderStat::
waitmessage B_WAIT_TIME_LONG
return
BattleScript_AbilityPopUpTarget:
BattleScript_AbilityPopUpTarget::
copybyte gBattlerAbility, gBattlerTarget
BattleScript_AbilityPopUp:
BattleScript_AbilityPopUp::
.if B_ABILITY_POP_UP == TRUE
showabilitypopup BS_ABILITY_BATTLER
pause 40
@ -7618,6 +7460,37 @@ BattleScript_EmergencyExitWild::
finishaction
return
BattleScript_EmergencyExitEnd2::
pause 5
call BattleScript_AbilityPopUp
pause B_WAIT_TIME_LONG
playanimation BS_ATTACKER, B_ANIM_SLIDE_OFFSCREEN
waitanimation
openpartyscreen BS_ATTACKER, BattleScript_EmergencyExitRetEnd2
switchoutabilities BS_ATTACKER
waitstate
switchhandleorder BS_ATTACKER, 2
returntoball BS_TARGET, FALSE
getswitchedmondata BS_ATTACKER
switchindataupdate BS_ATTACKER
hpthresholds BS_ATTACKER
printstring STRINGID_SWITCHINMON
switchinanim BS_ATTACKER, FALSE, TRUE
waitstate
switchineffects BS_ATTACKER
BattleScript_EmergencyExitRetEnd2:
end2
BattleScript_EmergencyExitWildEnd2::
pause 5
call BattleScript_AbilityPopUp
pause B_WAIT_TIME_LONG
playanimation BS_ATTACKER, B_ANIM_SLIDE_OFFSCREEN
waitanimation
setoutcomeonteleport BS_ATTACKER
finishaction
end2
BattleScript_TraceActivates::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUpScripting
@ -7660,6 +7533,7 @@ BattleScript_PickupActivates::
call BattleScript_AbilityPopUp
printstring STRINGID_XFOUNDONEY
waitmessage B_WAIT_TIME_LONG
tryrestorehpberry
BattleScript_PickupActivatesEnd:
end3
@ -7669,6 +7543,7 @@ BattleScript_HarvestActivates::
call BattleScript_AbilityPopUp
printstring STRINGID_HARVESTBERRY
waitmessage B_WAIT_TIME_LONG
tryrestorehpberry
BattleScript_HarvestActivatesEnd:
end3
@ -8231,24 +8106,6 @@ BattleScript_ItemNoStatLoss::
waitmessage B_WAIT_TIME_LONG
return
BattleScript_BRNPrevention::
pause B_WAIT_TIME_SHORT
printfromtable gBRNPreventionStringIds
waitmessage B_WAIT_TIME_LONG
return
BattleScript_PRLZPrevention::
pause B_WAIT_TIME_SHORT
printfromtable gPRLZPreventionStringIds
waitmessage B_WAIT_TIME_LONG
return
BattleScript_PSNPrevention::
pause B_WAIT_TIME_SHORT
printfromtable gPSNPreventionStringIds
waitmessage B_WAIT_TIME_LONG
return
BattleScript_ObliviousPreventsAttraction::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
@ -8299,25 +8156,13 @@ BattleScript_MoveUsedPsychicTerrainPrevents::
goto BattleScript_MoveEnd
BattleScript_GrassyTerrainHeals::
call BattleScript_GrassyTerrainHeals_Ret
end2
BattleScript_GrassyTerrainHeals_Ret::
setbyte gBattleCommunication, 0
BattleScript_GrassyTerrainLoop:
copyarraywithindex gBattlerAttacker, gBattlerByTurnOrder, gBattleCommunication, 1
checkgrassyterrainheal BS_ATTACKER, BattleScript_GrassyTerrainLoopIncrement
printstring STRINGID_GRASSYTERRAINHEALS
waitmessage B_WAIT_TIME_LONG
orword gHitMarker, HITMARKER_IGNORE_BIDE | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
BattleScript_GrassyTerrainLoopIncrement::
addbyte gBattleCommunication, 1
jumpifbytenotequal gBattleCommunication, gBattlersCount, BattleScript_GrassyTerrainLoop
bicword gHitMarker, HITMARKER_IGNORE_BIDE | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE
BattleScript_GrassyTerrainHealEnd:
return
end2
BattleScript_AbilityNoSpecificStatLoss::
pause B_WAIT_TIME_SHORT
@ -8469,10 +8314,9 @@ BattleScript_RaiseStatOnFaintingTarget::
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_RaiseStatOnFaintingTarget_End
copybyte gBattlerAbility, gBattlerAttacker
call BattleScript_AbilityPopUp
setgraphicalstatchangevalues
playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
waitanimation
printstring STRINGID_LASTABILITYRAISEDSTAT
printfromtable gStatUpStringIds
waitmessage B_WAIT_TIME_LONG
BattleScript_RaiseStatOnFaintingTarget_End:
return
@ -8641,6 +8485,29 @@ BattleScript_BattleBondActivatesOnMoveEndAttacker::
printstring STRINGID_ATTACKERBECAMEASHSPECIES
return
BattleScript_EffectBattleBondStatIncrease::
call BattleScript_AbilityPopUp
playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
setstatchanger STAT_ATK, 1, FALSE
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_EffectBattleBondStatIncreaseTrySpAtk
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_EffectBattleBondStatIncreaseTrySpAtk
printfromtable gStatUpStringIds
waitmessage B_WAIT_TIME_LONG
BattleScript_EffectBattleBondStatIncreaseTrySpAtk:
setstatchanger STAT_SPATK, 1, FALSE
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_EffectBattleBondStatIncreaseTrySpeed
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_EffectBattleBondStatIncreaseTrySpeed
printfromtable gStatUpStringIds
waitmessage B_WAIT_TIME_LONG
BattleScript_EffectBattleBondStatIncreaseTrySpeed:
setstatchanger STAT_SPEED, 1, FALSE
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_EffectBattleBondStatIncreaseRet
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_EffectBattleBondStatIncreaseRet
printfromtable gStatUpStringIds
waitmessage B_WAIT_TIME_LONG
BattleScript_EffectBattleBondStatIncreaseRet:
return
BattleScript_DancerActivates::
call BattleScript_AbilityPopUp
waitmessage B_WAIT_TIME_SHORT
@ -9770,7 +9637,7 @@ BattleScript_DamageNonTypesContinues::
printfromtable gDamageNonTypesDmgStringIds
waitmessage B_WAIT_TIME_LONG
effectivenesssound
hitanimation BS_SCRIPTING
hitanimation BS_ATTACKER
goto BattleScript_DoTurnDmg
BattleScript_EffectTryReducePP::
@ -9996,6 +9863,14 @@ BattleScript_EffectSteelsurge::
BattleScript_DynamaxBegins::
flushtextbox
trytrainerslidedynamaxmsg
jumpifcangigantamax BS_ATTACKER, BattleScript_DynamaxBegins_GigantamaxString_01
printstring STRINGID_TIMETODYNAMAX
waitmessage B_WAIT_TIME_MED
goto BattleScript_DynamaxBegins_SwitchIn
BattleScript_DynamaxBegins_GigantamaxString_01:
printstring STRINGID_TIMETOGIGANTAMAX
waitmessage B_WAIT_TIME_MED
BattleScript_DynamaxBegins_SwitchIn:
returnatktoball
pause B_WAIT_TIME_SHORT
returntoball BS_SCRIPTING, TRUE
@ -10003,6 +9878,15 @@ BattleScript_DynamaxBegins::
updatedynamax
playanimation BS_SCRIPTING, B_ANIM_DYNAMAX_GROWTH
waitanimation
jumpifbyteequal B_SHOW_DYNAMAX_MESSAGE, FALSE, BattleScript_DynamaxBegins_End3
jumpifcangigantamax BS_ATTACKER, BattleScript_DynamaxBegins_GigantamaxString_02
printstring STRINGID_PKMNDYNAMAXED
waitmessage B_WAIT_TIME_LONG
goto BattleScript_DynamaxBegins_End3
BattleScript_DynamaxBegins_GigantamaxString_02:
printstring STRINGID_PKMNGIGANTAMAXED
waitmessage B_WAIT_TIME_LONG
BattleScript_DynamaxBegins_End3:
end3
BattleScript_DynamaxEnds::
@ -10114,3 +9998,19 @@ BattleScript_SleepClausePreventsEnd::
printstring STRINGID_BLOCKEDBYSLEEPCLAUSE
waitmessage B_WAIT_TIME_LONG
end2
BattleScript_QuestionForfeitBattle::
printselectionstring STRINGID_QUESTIONFORFEITBATTLE
forfeityesnobox BS_ATTACKER
endselectionscript
BattleScript_ForfeitBattleGaveMoney::
getmoneyreward
.if B_WHITEOUT_MONEY >= GEN_4
printstring STRINGID_FORFEITBATTLEGAVEMONEY
.else
printstring STRINGID_PLAYERWHITEOUT2
.endif
waitmessage B_WAIT_TIME_LONG
end2

View File

@ -30,6 +30,7 @@
#include "constants/field_tasks.h"
#include "constants/field_weather.h"
#include "constants/flags.h"
#include "constants/follower_npc.h"
#include "constants/frontier_util.h"
#include "constants/game_stat.h"
#include "constants/item.h"
@ -45,9 +46,11 @@
#include "constants/party_menu.h"
#include "constants/pokedex.h"
#include "constants/pokemon.h"
#include "constants/rtc.h"
#include "constants/roulette.h"
#include "constants/script_menu.h"
#include "constants/secret_bases.h"
#include "constants/siirtc.h"
#include "constants/songs.h"
#include "constants/sound.h"
#include "constants/species.h"
@ -760,12 +763,12 @@ Common_EventScript_PlayGymBadgeFanfare::
return
Common_EventScript_OutOfCenterPartyHeal::
fadescreen FADE_TO_BLACK
fadescreenswapbuffers FADE_TO_BLACK
playfanfare MUS_HEAL
waitfanfare
special HealPlayerParty
callnative UpdateFollowingPokemon
fadescreen FADE_FROM_BLACK
fadescreenswapbuffers FADE_FROM_BLACK
return
EventScript_RegionMap::

View File

@ -80,7 +80,8 @@ gFieldEffectScriptPointers::
.4byte gFieldEffectScript_TracksBug @ FLDEFF_TRACKS_BUG
.4byte gFieldEffectScript_TracksSpot @ FLDEFF_TRACKS_SPOT
.4byte gFieldEffectScript_CaveDust @ FLDEFF_CAVE_DUST
.4byte gFieldEffectScript_Defog @ FLDEFF_DEFOG
gFieldEffectScript_ExclamationMarkIcon1::
field_eff_callnative FldEff_ExclamationMarkIcon
field_eff_end
@ -379,3 +380,7 @@ gFieldEffectScript_TracksSlither::
gFieldEffectScript_CaveDust::
field_eff_loadfadedpal_callnative gSpritePalette_CaveDust FldEff_CaveDust
field_eff_end
gFieldEffectScript_Defog::
field_eff_callnative FldEff_Defog
field_eff_end

View File

@ -474,6 +474,7 @@ BattleFrontier_BattleDomeBattleRoom_EventScript_SetUpObjects::
call BattleFrontier_EventScript_SetBrainObjectGfx
setobjectxyperm LOCALID_DOME_OPPONENT, 13, 9
removeobject LOCALID_DOME_OPPONENT
delay 1
addobject LOCALID_DOME_OPPONENT
applymovement LOCALID_DOME_OPPONENT, BattleFrontier_BattleDomeBattleRoom_Movement_SetInvisibleFacingUp
BattleFrontier_BattleDomeBattleRoom_EventScript_EndSetUpObjects::

View File

@ -47,13 +47,13 @@ MtChimney_EventScript_Maxie::
msgbox MtChimney_Text_MaxieYouHaventSeenLastOfMagma, MSGBOX_DEFAULT
closemessage
delay 30
fadescreen FADE_TO_BLACK
fadescreenswapbuffers FADE_TO_BLACK
removeobject LOCALID_MT_CHIMNEY_MAXIE
removeobject LOCALID_MT_CHIMNEY_MAGMA_GRUNT_1
removeobject LOCALID_MT_CHIMNEY_TABITHA
removeobject LOCALID_MT_CHIMNEY_MAGMA_GRUNT_2
setflag FLAG_HIDE_MT_CHIMNEY_TEAM_MAGMA
fadescreen FADE_FROM_BLACK
fadescreenswapbuffers FADE_FROM_BLACK
setobjectxyperm LOCALID_MT_CHIMNEY_ARCHIE, 10, 12
addobject LOCALID_MT_CHIMNEY_ARCHIE
call_if_eq VAR_FACING, DIR_EAST, MtChimney_EventScript_ArchieApproachPlayerEast

View File

@ -41,7 +41,7 @@ MtPyre_Summit_EventScript_TeamAquaExits::
call_if_eq VAR_0x8008, 2, MtPyre_Summit_EventScript_ArchieFacePlayer2
msgbox MtPyre_Summit_Text_ArchieWeGotTheOrbLetsGo, MSGBOX_DEFAULT
closemessage
fadescreen FADE_TO_BLACK
fadescreenswapbuffers FADE_TO_BLACK
removeobject LOCALID_MT_PYRE_SUMMIT_ARCHIE
removeobject LOCALID_MT_PYRE_SUMMIT_GRUNT_1
removeobject LOCALID_MT_PYRE_SUMMIT_GRUNT_2
@ -50,7 +50,7 @@ MtPyre_Summit_EventScript_TeamAquaExits::
setflag FLAG_HIDE_MT_PYRE_SUMMIT_ARCHIE
setflag FLAG_HIDE_MT_PYRE_SUMMIT_TEAM_AQUA
fadedefaultbgm
fadescreen FADE_FROM_BLACK
fadescreenswapbuffers FADE_FROM_BLACK
delay 20
setvar VAR_MT_PYRE_STATE, 1
call_if_eq VAR_0x8008, 0, MtPyre_Summit_EventScript_OldLadyApproachPlayer0

View File

@ -47,6 +47,7 @@ SlateportCity_BattleTentBattleRoom_EventScript_EnterRoom::
factory_setopponentgfx
setobjectxyperm LOCALID_SLATEPORT_TENT_BATTLE_OPPONENT, 5, 1
removeobject LOCALID_SLATEPORT_TENT_BATTLE_OPPONENT
delay 1
addobject LOCALID_SLATEPORT_TENT_BATTLE_OPPONENT
applymovement LOCALID_SLATEPORT_TENT_BATTLE_OPPONENT, SlateportCity_BattleTentBattleRoom_Movement_OpponentEnter
waitmovement 0

View File

@ -584,3 +584,34 @@ Debug_EventScript_FontTest::
@Debug_EventScript_InflictStatus1_Close:
@ releaseall
@ end
Debug_EventScript_TellTheTime::
callnative DebugMenu_CalculateTime
msgbox Debug_EventScript_TellTheTime_Text_0, MSGBOX_DEFAULT
waitmessage
closemessage
end
Debug_EventScript_PrintTimeOfDay::
callnative DebugMenu_CalculateTimeOfDay
msgbox DebugEventScript_PrintWeekday_Text_0, MSGBOX_DEFAULT
waitmessage
closemessage
end
Debug_EventScript_FakeRTCNotEnabled::
msgbox Debug_EventScript_FakeRTCNotEnabled_Text_0, MSGBOX_DEFAULT
waitmessage
closemessage
return
Debug_EventScript_FakeRTCNotEnabled_Text_0:
.string "You currently do not have Fake RTC\nenabled. Please enable it in include/\lconfig/overworld.h$"
Debug_EventScript_TellTheTime_Text_0:
.string "Time and date:\n"
.string "{STR_VAR_1}, {STR_VAR_2}:{STR_VAR_3}$"
DebugEventScript_PrintWeekday_Text_0:
.string "Time of day: {STR_VAR_1}$"

View File

@ -293,7 +293,9 @@ EventScript_UseWaterfall::
msgbox Text_WantToWaterfall, MSGBOX_YESNO
goto_if_eq VAR_RESULT, NO, EventScript_EndWaterfall
msgbox Text_MonUsedWaterfall, MSGBOX_DEFAULT
hidefollowernpc
dofieldeffect FLDEFF_USE_WATERFALL
callnative FollowerNPC_WarpSetEnd
goto EventScript_EndWaterfall
EventScript_CannotUseWaterfall::
@ -321,12 +323,16 @@ EventScript_UseDive::
lockall
checkpartymove MOVE_DIVE
goto_if_eq VAR_RESULT, PARTY_SIZE, EventScript_CantDive
copyvar 0x8004 VAR_RESULT
bufferpartymonnick STR_VAR_1, VAR_RESULT
setfieldeffectargument 0, VAR_RESULT
setfieldeffectargument 1, 1
msgbox Text_WantToDive, MSGBOX_YESNO
goto_if_eq VAR_RESULT, NO, EventScript_EndDive
msgbox Text_MonUsedDive, MSGBOX_DEFAULT
hidefollowernpc
setfieldeffectargument 0, VAR_0x8004
setfieldeffectargument 1, 1
dofieldeffect FLDEFF_USE_DIVE
goto EventScript_EndDive
end
@ -348,8 +354,9 @@ EventScript_UseDiveUnderwater::
setfieldeffectargument 0, VAR_RESULT
setfieldeffectargument 1, 1
msgbox Text_WantToSurface, MSGBOX_YESNO
goto_if_eq VAR_RESULT, NO, EventScript_EndSurface
goto_if_eq VAR_RESULT, NO, EventScript_NoSurface
msgbox Text_MonUsedDive, MSGBOX_DEFAULT
hidefollowernpc
dofieldeffect FLDEFF_USE_DIVE
goto EventScript_EndSurface
end
@ -361,6 +368,8 @@ EventScript_CantSurface::
end
EventScript_EndSurface::
callnative SetFollowerNPCSurfSpriteAfterDive
EventScript_NoSurface::
releaseall
end
@ -418,3 +427,20 @@ EventScript_FailSweetScent::
Text_FailSweetScent:
.string "Looks like there's nothing here…$"
EventScript_UseDefog::
lockall
bufferpartymonnick STR_VAR_1, VAR_RESULT
buffermovename STR_VAR_2, MOVE_DEFOG
msgbox Text_MonUsedFieldMove, MSGBOX_DEFAULT
closemessage
isfollowerfieldmoveuser VAR_0x8004
setfieldeffectargument 3, VAR_0x8004 @ skip pose if so
setflag FLAG_SAFE_FOLLOWER_MOVEMENT
call_if_eq VAR_0x8004, TRUE, EventScript_FollowerFieldMove
waitmovement 0
setfieldeffectargument 0, VAR_RESULT
dofieldeffect FLDEFF_DEFOG
waitstate
releaseall
end

View File

@ -43,19 +43,19 @@ Common_Movement_WalkInPlaceFasterDown:
walk_in_place_faster_down
step_end
Common_Movement_FaceRight:
Common_Movement_FaceRight::
face_right
step_end
Common_Movement_FaceLeft:
Common_Movement_FaceLeft::
face_left
step_end
Common_Movement_FaceDown:
Common_Movement_FaceDown::
face_down
step_end
Common_Movement_FaceUp:
Common_Movement_FaceUp::
face_up
step_end
@ -96,7 +96,7 @@ Common_Movement_Delay32:
delay_16
step_end
Common_Movement_WalkUp:
Common_Movement_WalkUp::
walk_up
step_end
@ -105,3 +105,64 @@ Common_Movement_WalkUp2::
walk_up
walk_up
step_end
@ Follower NPC
Common_Movement_WalkUpSlow::
walk_slow_up
step_end
Common_Movement_WalkDownSlow::
walk_slow_down
step_end
Common_Movement_WalkRightSlow::
walk_slow_right
step_end
Common_Movement_WalkLeftSlow::
walk_slow_left
step_end
Common_Movement_WalkDown::
walk_down
step_end
Common_Movement_WalkRight::
walk_right
step_end
Common_Movement_WalkLeft::
walk_left
step_end
Common_Movement_WalkUpFast::
walk_fast_up
step_end
Common_Movement_WalkDownFast::
walk_fast_down
step_end
Common_Movement_WalkRightFast::
walk_fast_right
step_end
Common_Movement_WalkLeftFast::
walk_fast_left
step_end
Common_Movement_WalkUpFaster::
walk_faster_up
step_end
Common_Movement_WalkDownFaster::
walk_faster_down
step_end
Common_Movement_WalkRightFaster::
walk_faster_right
step_end
Common_Movement_WalkLeftFaster::
walk_faster_left
step_end

1
docs/CONTRIBUTING.md Normal file
View File

@ -0,0 +1 @@
{{#include ../CONTRIBUTING.md}}

1
docs/CREDITS.md Normal file
View File

@ -0,0 +1 @@
{{#include ../CREDITS.md}}

403
docs/STYLEGUIDE.md Normal file
View File

@ -0,0 +1,403 @@
# Styleguide and Principles
## Naming Conventions
Function names and struct names should be formatted in `PascalCase`.
```c
void ThisIsCorrect(void);
struct MyStruct
{
u8 firstField;
u16 secondField;
...
};
```
Variables and struct fields should be formatted in `camelCase`.
```c
int thisIsCorrect = 0;
```
Global variables should be prefixed with `g`, and static variables should be
prefixed with `s`.
```c
extern s32 gMyGlobalVariable;
static u8 sMyStaticVariable = 0;
```
Macros and constants should use `CAPS_WITH_UNDERSCORES`.
```c
#define MAX_LEVEL 100
enum
{
COLOR_RED,
COLOR_BLUE,
COLOR_GREEN,
};
#define ADD_FIVE(x) ((x) + 5)
```
## Coding Style
### Comments
Ideally, contributions have descriptive variable, function and constant names so as to explain functionality without comments. When a comment is used, the content of the comment should explain _WHY_ a specific system or component works the way it does.
When describing a system/component in-depth, use block comment syntax.
```c
/*
* This is an in-depth description of the save block format. Its format is as follows:
*
* Sectors 0 - 13: Save Slot 1
* Sectors 14 - 27: Save Slot 2
* ...
*/
```
When briefly describing a function or block of code, use a single-line comments
placed on its own line.
There should be a single space directly to the right of `//`.
```c
// This is supplemental information for the function. If there is a bunch of info, it should
// carry on to the next line.
void ProcessSingleTask(void)
{
// Short comment describing some noteworthy aspect of the code immediately following.
...
// Comments should be capitalized and end in a period.
}
```
When tagging a data structure that corresponds to an `enum` or some noteworthy
value, place the comment on the same line as the code.
```c
const u8 gPlantlikeMons[] =
{
FALSE, // SPECIES_BULBASAUR
FALSE, // SPECIES_IVYSAUR
TRUE, // SPECIES_VENUSAUR
FALSE, // SPECIES_CHARMANDER
...
};
```
### Whitespace
All `.c` and `.h` files should use 4 spaces--not tabs.
Assembler files (`.s)` use tabs.
Script files (`.inc)` use tabs.
### Operators
Assignments and comparison operators should have one space on both sides of `=`.
```c
int i = 0; // correct
int i=0; // incorrect
a > b // correct
a>b // incorrect
```
The incrementor and decrementor operators should NOT have a space.
```c
i++; // correct
i ++; // incorrect
```
A control statement should have a space between them and their expressions, and the opening bracket should be on the next line.
```c
for (...)
{
// correct
}
for(...) {
// incorrect
}
```
A `switch` statement's cases should left-align with the `switch`'s block.
```c
switch (foo)
{
case 0: // correct
...
break;
}
switch (foo)
{
case 0: // incorrect
...
break;
}
```
A single empty line should follow a block.
```c
int MyFunction(int bar)
{
int foo = 0;
if (bar)
foo++;
return foo; // correct
}
int MyFunction(int bar)
{
int foo = 0;
if (bar)
foo++;
return foo; // incorrect
}
```
A chain of `if-else` statements in which any block is more than one line of
code should use braces. If all blocks are single-line, then no braces are necessary.
```c
if (foo) // correct
{
return 1;
}
else
{
MyFunction();
return 0;
}
if (foo) // incorrect
return 1;
else
{
MyFunction();
return 0;
}
```
### Control Structures
When comparing whether or not a value equals `0`, don't be explicit unless the
situation calls for it.
```c
if (runTasks) // correct
RunTasks();
if (runTasks != 0) // incorrect
RunTasks();
if (!PlayerIsOutside()) // correct
RemoveSunglasses();
if (PlayerIsOutside() == 0) // incorrect
RemoveSunglasses();
```
When writing a `for` or `while` loop with no body, use a semicolon `;` on the
same line, rather than empty braces.
```c
for (i = 0; gParty[i].species != SPECIES_NONE; i++); // correct
for (i = 0; gParty[i].species != SPECIES_NONE; i++) // incorrect
{ }
```
### Inline Configs
When adding functionality that is controlled by a config, defines should be checked within the normal control flow of the function unless a data structure requires a change at runtime.
```c
void SetCurrentDifficultyLevel(enum DifficultyLevel desiredDifficulty)
{
#ifdef B_VAR_DIFFICULTY
return; // Incorrect
#endif
if (desiredDifficulty > DIFFICULTY_MAX)
desiredDifficulty = DIFFICULTY_MAX;
VarSet(B_VAR_DIFFICULTY, desiredDifficulty);
}
```
```c
void SetCurrentDifficultyLevel(enum DifficultyLevel desiredDifficulty)
{
if (!B_VAR_DIFFICULTY) // Correct
return;
if (desiredDifficulty > DIFFICULTY_MAX)
desiredDifficulty = DIFFICULTY_MAX;
VarSet(B_VAR_DIFFICULTY, desiredDifficulty);
}
```
```c
[MOVE_VINE_WHIP] =
{
.name = COMPOUND_STRING("Vine Whip"),
.description = COMPOUND_STRING(
"Strikes the foe with\n"
"slender, whiplike vines."),
#if B_UPDATED_MOVE_DATA >= GEN_6 // Correct
.pp = 25,
#elif B_UPDATED_MOVE_DATA >= GEN_4
.pp = 15,
#else
.pp = 10,
#endif
.effect = EFFECT_HIT,
.power = B_UPDATED_MOVE_DATA >= GEN_6 ? 45 : 35,
},
```
## Data Type Sizes
When a variable number is used, the data type should generally `u32` (unsigned) or `s32` (signed). There are a few exceptions to this rule, such as:
* Values stored in the saveblock should use the smallest data type possible.
* `EWRAM` variables should use the smallest data type possible.
* Global variables / global struct members use the smallest data type possible.
## Constants, Enums and Type Checking
Avoid using magic numbers when possible - constants help to make clear why a specific value is used.
```c
// Incorrect
if (gimmick == 5 && mon->teraType != 0)
return TRUE;
if (gimmick == 4 && mon->shouldUseDynamax)
return TRUE;
```
```c
// Correct
#define TYPE_NONE 0
#define GIMMICK_DYNAMAX 4
#define GIMMICK_TERA 5
if (gimmick == GIMMICK_TERA && mon->teraType != TYPE_NONE)
return TRUE;
if (gimmick == GIMMICK_DYNAMAX && mon->shouldUseDynamax)
return TRUE;
```
When several numbers in sequence are used AND those values are not utilized in the saveblock, an enum is used instead.
```c
//Correct
enum Gimmick
{
GIMMICK_NONE,
GIMMICK_MEGA,
GIMMICK_ULTRA_BURST,
GIMMICK_Z_MOVE,
GIMMICK_DYNAMAX,
GIMMICK_TERA,
GIMMICKS_COUNT,
};
if (gimmick == GIMMICK_TERA && mon->teraType != TYPE_NONE)
return TRUE;
if (gimmick == GIMMICK_DYNAMAX && mon->shouldUseDynamax)
return TRUE;
```
When an enum is used, the enum type is used instead of a regular number type to prevent incorrectly set values.
```c
// Incorrect
bool32 CanActivateGimmick(u32 battler, u32 gimmick)
{
return gGimmicksInfo[gimmick].CanActivate != NULL && gGimmicksInfo[gimmick].CanActivate(battler);
}
u32 GetCurrentDifficultyLevel(void)
{
if (!B_VAR_DIFFICULTY)
return DIFFICULTY_NORMAL;
return VarGet(B_VAR_DIFFICULTY);
}
```
```c
//Correct
bool32 CanActivateGimmick(u32 battler, enum Gimmick gimmick)
{
return gGimmicksInfo[gimmick].CanActivate != NULL && gGimmicksInfo[gimmick].CanActivate(battler);
}
enum DifficultyLevel GetCurrentDifficultyLevel(void)
{
if (!B_VAR_DIFFICULTY)
return DIFFICULTY_NORMAL;
return VarGet(B_VAR_DIFFICULTY);
}
```
### Data file format
External data files should use JSON.
## Principles
### Minimally Invasive
New functionality must be as minimally invasive to existing files as possible. When a large amount of new code is introduced, it is best to isolate it in its own file.
The [`B_VAR_DIFFICULTY`](https://patch-diff.githubusercontent.com/raw/rh-hideout/pokeemerald-expansion/pull/5337.diff) pull request is a good example of lots of new code being introduced in minimally invasive ways.
### `UNUSED`
If a function or data is introduced but is never called, it is designated as `UNUSED`. `UNUSED` functions should not be introduced unless neccesary.
```c
static void UNUSED PadString(const u8 *src, u8 *dst)
{
u32 i;
for (i = 0; i < 17 && src[i] != EOS; i++)
dst[i] = src[i];
for (; i < 17; i++)
dst[i] = CHAR_SPACE;
dst[i] = EOS;
}
```
### Config Philosophy
If a branch can modifies saves, the functionality that does so must be gated behind a config, and off by default.
If a branch has a config that performs either of the following, it should be on by default:
* improves the backend / developer quality of life
* emulates present day, modern day Pokémon
If a branch's behavior is one that Game Freak does not have a consistent stance on, the default behavior of the config should be disussed by the maintainers.
All other configs should be off.
### Save Philosophy
Until [save migration](https://discord.com/channels/419213663107416084/1108733346864963746) is implemented, branches will only merged in if they do not forcefully break existing game saves.
When `pokemeerald-expansion` gets to a point where new functionality will require that we break saves, we will merge as many [save-breaking features](https://discord.com/channels/419213663107416084/1202774957776441427) together as possible, and increment the major version number of the project.
# Attribution
* The majority of the styleguide was written by [garakmon](https://github.com/garakmon) as part of their [PR to pokefirered](<https://github.com/pret/pokefirered/pull/63>).

View File

@ -5,6 +5,8 @@
- [Setting up WSL1 (Legacy Portion)](./legacy_WSL1_INSTALL.md)
- [Run documentation site locally](local_mdbook/index.md)
- [Ubuntu WSL1/WSL2](local_mdbook/ubuntu_WSL.md)
- [Contributing](./CONTRIBUTING.md)
- [Credits](./CREDITS.md)
- [Tutorials]()
- [What are AI Flags?](tutorials/ai_flags.md)
- [How to add new AI Flags](tutorials/ai_logic.md)
@ -15,6 +17,7 @@
- [v1.6.x and earlier](tutorials/how_to_new_pokemon_1_6_0.md)
- [How to use the Testing System](tutorials/how_to_testing_system.md)
- [How to add new Trainer Slides](tutorials/how_to_new_trainer_slide.md)
- [Day/Night System FAQ](tutorials/dns.md)
- [Changelog](./CHANGELOG.md)
- [1.11.x]()
- [Version 1.11.4](changelogs/1.11.x/1.11.4.md)

View File

@ -139,7 +139,7 @@ If the changelog you're making is for a minor version (Eg. 1.3.0), make sure to
#define EXPANSION_VERSION_MAJOR 1
#define EXPANSION_VERSION_MINOR 2
#define EXPANSION_VERSION_PATCH 3
// FALSE if this this version of Expansion is not a tagged commit, i.e.
// it contains unreleased changes.
-#define EXPANSION_TAGGED_RELEASE FALSE
@ -164,7 +164,7 @@ If the changelog you're making is for a minor version (Eg. 1.3.0), make sure to
#define EXPANSION_VERSION_MINOR 2
- #define EXPANSION_VERSION_PATCH 3
+ #define EXPANSION_VERSION_PATCH 4
// FALSE if this this version of Expansion is not a tagged commit, i.e.
// it contains unreleased changes.
-#define EXPANSION_TAGGED_RELEASE TRUE

View File

@ -0,0 +1,70 @@
# Document Purpose
This document is a guide for maintainers to account for all the reccomended steps before merging in a pull request.
<!-- Here's an optional markdown checklist version that you can post in your reviews. -->
<!-- https://files.catbox.moe/nqxvnl.md -->
# Checklist
## Is the branch's theoretical functionality in scope?
If you're not sure if a branch's functionality is [in scope](docs/team_procedures/scope.md), start a conversation on Discord to resolve.
## Does the branch successfully compile?
From `make clean`, the branch should locally compile.
## Do all CI tests pass?
Contributors are asked to make sure tests pass locally, but maintainers should at least wait for the CI to pass before merging.
## Have you verified that the functionality works in game without any problems?
If functionality cannot be verified with an automated test, proof of an in game test is required. Do not be afraid to reach out to the contributor or the community to make sure something works in game as it should.
## If the branch ports behavior from another Pokémon game, have you verified that the behavior functions as faithfully as possible?
We have always tried to make sure we can mimic the original functionality as closely as possible so as to avoid confusion with users and players. Do not be afraid to ask the contributor / community for proof if you cannot personally verify.
## If the branch is a popular feature within the community with an established feature branch, is this using that established branch as a base?
There are situations where this should and should not happen, and should be discussed with maintainers on a case by case basis.
## If this branch changes a function that is expected to be modified by users, is there a migration script?
Not everything needs a migration script - if you're unsure, start a discussion.
## Should new functionality introduced by this branch be gated behind a config?
We don't have a strict definition of when configs should be used, but you can start with
> Why SHOULDN'T this be a config?
## Are tests written for everything that can be tested?
If you're not sure if something CAN be tested, start a discussion. Some contributors may not be capable of writing tests - we should guide them in #expansion-tests to do so.
If any new tests are `KNOWN_FAILING`, issues should be opened describing each of the `KNOWN_FAILING` tests and our understanding of why they fail.
## Does the branch meet our [config philosophy](/docs/STYLEGUIDE.md#config-philosophy)?
## Does the branch meet our [saves philosophy](/docs/STYLEGUIDE.md#saves-philosophy)?
## Does the submitted code follow the [styleguide](/docs/STYLEGUIDE.md)?
This applies to code that comes from other branches or games.
## Is the pull request appropriately labeled?
Without labels, the CHANGELOG will not be properly formatted. For specifically the `bugfix` label, an additional label, detailing what area the bug exists in is required.
## Is `pokeemerald-expansion` free from a merge freeze?
Our [release schedule](/docs/team_procedures/schedule.md) prevents us from merging Big Features and non-bugfixes within certain dates close to a release. Please use `/release` in the RHH Discord to clarify when these are occuring.
# Merging
When a feature has passed all of the items on the checklist, it is ready to be merged. From GitHub's interface, there are three different options for merging:
## Squash and merge
This should be used for all PRs _except_ when merging from either:
* a publicly available feature branch from by the community OR
* `upcoming`, `master` or `pret/pokeemerald`.
## Create a merge commit
Use the "Create a merge commit" to preserve history if:
- The branch is a publicly available feature branch from the community
- It's a upstream `pret` merge
- It's a `master` to `upcoming` merge
- It's a Release merge
## Rebase and merge
We do not use this ever.

View File

@ -12,8 +12,13 @@ Releases that focus primarily on bugfixes or improvements to the test system. Pa
PRs with the Github label [`type: big feature`](https://github.com/rh-hideout/pokeemerald-expansion/issues?q=sort%3Aupdated-desc+is%3Aopen+label%3A%22type%3A+big+feature%22) will NOT be merged until after the next Minor Release.
### Merge Freeze (14 days to the next Minor Release)
PRs that DO NOT have the Github labels [`bugfix`](https://github.com/rh-hideout/pokeemerald-expansion/issues?q=sort%3Aupdated-desc+label%3Abugfix) or [`type: cleanup`](https://github.com/rh-hideout/pokeemerald-expansion/issues?q=sort%3Aupdated-desc+label%3A%22type%3A+cleanup%22+) will NOT be merged until after the next Minor Release.
Pull Requests that **DO NOT** have one of the following Github labels:
- [`bugfix`](https://github.com/rh-hideout/pokeemerald-expansion/issues?q=sort%3Aupdated-desc+label%3Abugfix)
- [`type: cleanup`](https://github.com/rh-hideout/pokeemerald-expansion/issues?q=sort%3Aupdated-desc+label%3A%22type%3A+cleanup%22+)
- [`type: credits`](https://github.com/rh-hideout/pokeemerald-expansion/issues?q=sort%3Aupdated-desc+label%3A%22type%3A+credits%22+)
- [`type: documentation`](https://github.com/rh-hideout/pokeemerald-expansion/issues?q=sort%3Aupdated-desc+label%3A%22type%3A+documentation%22+)
- [`category: battle-tests`](https://github.com/rh-hideout/pokeemerald-expansion/issues?q=sort%3Aupdated-desc+is%3Aopen+label%3A%22category%3A+battle-tests%22)
will NOT be merged until after the next Minor Release.
### Sample Schedule
| Major | Minor | Patch | Type | Goal Date |

View File

@ -5,9 +5,9 @@ This document is a guide for contributors and Senate to decide if a feature is w
# Definitions
* **Showdown Supported (SS)**: A core series game who's metagame can be played on Showdown.
* Includes every [core series game](https://bulbapedia.bulbagarden.net/wiki/Core_series#List_of_core_series_games) except Pokémon Legends: Arceus.
* Includes every [core series game](https://bulbapedia.bulbagarden.net/wiki/Core_series#List_of_core_series_games) except Pokémon Legends: Arceus.
* Does not include [spin-off games](https://bulbapedia.bulbagarden.net/wiki/Spin-off_Pokémon_games) such as Pokémon Colosseum, Pokémon XD, Pokémon Trozei!, etc.
* **Base Expansion Version**: "A .gba file built from an unmodified `master` or `upcoming` branch of `pokeemerald-expansion`.
* **Base Expansion Version**: "A .gba file built from an unmodified `master` or `upcoming` branch of `pokeemerald-expansion`.
* **Vanilla Emerald Version**: A .gba file built from an unmodified `master` branch of pret's `pokeemerald`.
# Guidelines
@ -19,14 +19,14 @@ A pull request meets the scope criteria if:
## In Scope Categories
1. **SS Species**: Adds Species that have appeared in a Showdown-supported title. Includes follower sprites for all defined species including battle-only ones (ie. Megas)
2. **SS Moves**: Adds Moves and Move Animations that have appeared in a Showdown-supported title
3. **SS Abilities**: Adds Abilities that have appeared in a Showdown-supported title
4. **SS Items**: Adds Items that have appeared in a Showdown-supported title
2. **SS Moves**: Adds Moves and Move Animations that have appeared in a Showdown-supported title
3. **SS Abilities**: Adds Abilities that have appeared in a Showdown-supported title
4. **SS Items**: Adds Items that have appeared in a Showdown-supported title
5. **SS Gimmicks**: Adds Gimmicks that have appeared in a Showdown-supported title (Dynamax, Mega Evolution, etc.)
6. **SS Battle Types**: Adds Special Battle Types that have appeared in a Showdown-supported title (Triple battles, etc.)
7. **SS Battle Mechanics**: Adds mechanical battle changes that have appeared in a Showdown-supported title, and allow developers to choose which generation suits them where applicable
8. **Battle AI Behaviour**: Improvements towards the capability of a human competitive player, and unique or interesting behaviours otherwise
9. **Base Link Compatibility**: The ability for two Base Expansion Version's to connect, trade, and battle one another
9. **Base Link Compatibility**: The ability for two Base Expansion Version's to connect, trade, and battle one another
10. **SS Overworld Features**: Add overworld changes / additions from Showdown-supported Pokémon titles (followers, raids, sideways stairs, etc.)
11. **SS Menu Features**: Add menu changes / additions from Showdown-supported Pokémon titles (type effectivness indicator, PC functions, etc.)
12. **Speed Up**: Optimize code to run more efficiently, take up less space, and work better overall to improves the developer and / or player experience
@ -41,7 +41,7 @@ A pull request meets the scope criteria if:
3. **Non-SS Abilities**: Adds Abilities that have NOT appeared in a Showdown-supported title
4. **Non-SS Items**: Adds Items that have NOT appeared in a Showdown-supported title
5. **Non-SS Gimmicks**: Adds Gimmicks that have NOT appeared in a Showdown-supported title (Showdown's Other Metagames, etc.)
6. **Non-SS Battle Types**: Adds Special Battle Types that have NOT appeared in a Showdown-supported title
6. **Non-SS Battle Types**: Adds Special Battle Types that have NOT appeared in a Showdown-supported title
7. **Overworld Maps**: Adds overworld maps from either Showdown-supported titles or non-Showdown-supported titles
8. **Duplicate UIs**: Adds additional user interface that covers the same functionality of an existing feature (HGSS Pokédex, BW Summary Screen, etc.)
9. **Vanilla Link Compatibility**: The ability for Base Expansion Version and Vanilla Emerald Version to connect, trade, and battle one another
@ -50,8 +50,8 @@ A pull request meets the scope criteria if:
Pull Requests that fall into this category are not in scope by default and should be brought up to maintainers, who will discuss and vote as to whether or not the feature is considered in scope. Considerations for acceptance may include invasiveness of implementation, popularity, ease of maintenance, etc.
1. **Developer Ease of Use**: Lowers barrier of entry for developers to use existing behavior
2. **Fangame Features**: Adds a popular feature from other fangames
1. **Developer Ease of Use**: Lowers barrier of entry for developers to use existing behavior
2. **Fangame Features**: Adds a popular feature from other fangames
3. **Popular Non-SS Features**: Exceptions can be made for uniquely popular or requested features (Drowsy, PLA Legend Plate, etc.)
4. **External Program**: External programs like poryscript, porymoves, etc.
5. **Intergenerational Feature Compatibility**: Addresses limitations and issues resulting from including all generational behaviours in a GBA native title, and extrapolation of features no longer supported by GameFreak

View File

@ -179,3 +179,9 @@ AI will determine whether it would switch out in the player's situation or not,
## `AI_FLAG_PREDICT_INCOMING_MON`
This flag requires `AI_FLAG_PREDICT_SWITCH` to function. If the AI predicts that the player will switch, this flag allows the AI to run its move scoring calculation against the Pokémon it expects the player to switch into, instead of the Pokémon that it expects to switch out.
## `AI_FLAG_PREDICT_MOVE`
AI will predict what move the player is going to use based on what move it would use in the same situation. Generally works best if also using `AI_FLAG_OMNISCIENT`.
## `AI_FLAG_PP_STALL_PREVENTION`
This flag aims to prevent the player from PP stalling the AI by switching between immunities. The AI mon's move scores will slowly decay for absorbed moves over time, eventually making its moves unpredictable. More detailed control for this behaviour can be customized in the `ai.h` config file.

62
docs/tutorials/dns.md Normal file
View File

@ -0,0 +1,62 @@
## Day/Night system FAQ
### Q: How do I disable DNS?
A: Set `OW_ENABLE_DNS` to `FALSE` in `include/config/overworld.h`.
### Q: What map changes should be made for DNS?
A: By default, the only Hoenn map changes that need to be made are to edit the Lavaridge Town map to change the metatiles the two old ladies are on in the hot springs to be the normal hot spring water tile. This is to avoid a visual bug from when `OW_OBJECT_VANILLA_SHADOWS` is FALSE.
However, by default no maps have lighting effects of any kind. The rest of this tutorial is to aid in adding lighting effects.
If you intend to use vanilla maps and have not already edited them, revert commit [a5b079d833f18f66ebd53ac77f00227ae4a1f389](https://github.com/rh-hideout/pokeemerald-expansion/pull/6562/commits/a5b079d833f18f66ebd53ac77f00227ae4a1f389). This commit includes a lot of tileset, metatile, and palette changes to accommodate light-blending, and applies `OBJ_EVENT_GFX_LIGHT_SPRITE` where they make sense.
If you _have_ edited vanilla maps, the merge conflicts from reverting that commit will cause problems. If you are using vanilla maps, manually copy some of the tileset changes, `.pal`, and `.pla` files in your branch, and begin rebuilding your metatiles to have windows use the palettes that have a `.pla` for light blending the correct color slots. [Triple-layer metatiles](https://github.com/pret/pokeemerald/wiki/Triple-layer-metatiles) are highly recommended.
You will also want to add the lighting object events from that commit.
If you are not using Hoenn maps, the primary concern is that you do not use the exact same palette indices for colors you want to be darkened during night time and colors you want to light up. Err towards not light blending a color if you aren't sure how to avoid conflicts.
When writing map scripts, `fadescreenswapbuffers` should be preferred over `fadescreen`. This is to avoid odd behavior from the GBA's limitations in alpha blending.
### Q: How do I make lightbulbs glow?
![Rustboro before adding lamp object events](/docs/tutorials/img/dns/without_lamp.png)
![Rustboro after adding lamp object events](/docs/tutorials/img/dns/with_lamp.png)
A: Making lamps glow is not part of the tileset itself. Instead, place certain object events on top of where you desire a glowing effect.
These object events should use `OBJ_EVENT_GFX_LIGHT_SPRITE` and then as their `trainer_sight_or_berry_tree_id` (called Sight Radius/Berry Tree ID in porymap), use `LIGHT_TYPE_BALL` for round lights (such as candles or gas lamps), `LIGHT_TYPE_PKMN_CENTER_SIGN` over a Pok&eacute;mon Center sign, or `LIGHT_TYPE_POKE_MART_SIGN` over a Pok&eacute;mart sign.
### Q: How do I mark certain colors in a palette as light-blended?
A: Create a `.pla` file in the same folder as the `.pal` with the same name. This can be done on any kind of palette; the commit to revert listed up above only applies it to tilesets, but you could easily do it for object events as well. Of note, there is a [commit reverted for being out of scope](https://github.com/rh-hideout/pokeemerald-expansion/pull/6562/commits/348f5967ac8d383c827b415e1040234a3f28626f) to make a follower Ampharos's tail glow.
In this file you can enter color indices [0,15]
on separate lines to mark those colors as being light-blended, i.e:
`06.pla:`
```
# A comment
0 # if color 0 is listed, uses it to blend with instead of the default!
1
9
10
```
During the day time, these color indices appear as normal, but will be blended with either yellow or the 0 index at night. These indices should only be used for things you expect to light up. If you are using [porytiles](https://github.com/grunt-lucas/porytiles/wiki), palette overrides and using slight alterations to a color will aid you in avoiding color conflicts where the wrong index is assigned.
![Rustboro gym after light-blending the windows](/docs/tutorials/img/dns/window_lights.png)
The windows appear as normal during the day time (blue) and light up in the night. These use the default color.
### Q: How do I return to using regular shadows?
A: Set `OW_OBJECT_VANILLA_SHADOWS` to `TRUE` in `include/config/overworld.h`.
### Q: What graphical errors are likely to occur while using DNS?
A: If you have `OW_POPUP_GENERATION` set to `GEN_5` and `OW_POPUP_BW_ALPHA_BLEND` set to `TRUE`, you may have color errors during map popups. This is due to the GBA being severely limited in use of color blending and having both the overworld blended and the popup blended is difficult.
If you have `OW_OBJECT_VANILLA_SHADOWS` set to `TRUE`, this will also cause visual errors.
Any other graphical error should be reported.
### Q: How do I disable shadows for certain locations?
A: Shadows can be disabled for certain locations by modifying the `CurrentMapHasShadows` function in `src/overworld.c`.

View File

@ -46,9 +46,9 @@ void GetCodeFeedback(void)
gSpecialVar_Result = 1;
+ else if (!StringCompare(gStringVar2, sText_CaughtEmAll))
+ {
+ // TODO
+ // TODO
+ gSpecialVar_Result = 2;
+ }
+ }
else
gSpecialVar_Result = 0;
}
@ -71,7 +71,7 @@ void GetCodeFeedback(void)
+ GetSetPokedexFlag(i + 1, FLAG_SET_CAUGHT);
+ }
gSpecialVar_Result = 2;
}
}
else
gSpecialVar_Result = 0;
}

View File

@ -0,0 +1,58 @@
# How to Use Follower NPCs
*Written by Bivurnum*
*gif by ghoulslash*
![follower-npc](/docs/tutorials/img/follower_npc/follower-npc.gif)
## Configs
The configs for follower NPCs can be found in [include/config/follower_npc.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/upcoming/include/config/follower_npc.h).
* `FNPC_ENABLE_NPC_FOLLOWERS`: This must be set to `TRUE` in order to enable follower NPCs. It is `FALSE` by default as it adds some size to the save block.
* `FNPC_FLAG_HEAL_AFTER_FOLLOWER_BATTLE`: The player's party can be automatically healed after every partner battle. Set it to a flag to toggle it on/off with scripts, or set it to `FNPC_ALWAYS` to have it happen every time.
* `FNPC_FLAG_PARTNER_WILD_BATTLES`: The battle partner can join the player for wild battles. Set it to a flag to toggle it on/off with scripts, or set it to `FNPC_ALWAYS` to have it happen every time.
* `FNPC_NPC_FOLLOWER_WILD_BATTLE_VS_2`: Wild battles with a battle partner default to two wild Pokémon appearing. You can set this to `FALSE` to make only one wild Pokémon appear.
* `FNPC_NPC_FOLLOWER_PARTY_PREVIEW`: By default, a preview of the player's and partner's teams will be shown at the start of every trainer battle. Set this to `FALSE` to disable this feature.
* `FNPC_FACE_NPC_FOLLOWER_ON_DOOR_EXIT`: If `TRUE` the player will turn to face the follower when they exit a doorway.
* `FNPC_NPC_FOLLOWER_SHOW_AFTER_LEAVE_ROUTE`: If `TRUE` the follower will walk out of the player automatically after using Fly, Teleport, or Escape Rope.
## Set the Follower
The `setfollowernpc` macro will turn the specified object into an NPC follower. It requires the object id, the [follower flags](#follower-flags), and optionally a custom script and a [battle partner](#battle-partner). If you do not include a custom script name (or you set it to `0`), the NPC follower will default to their normal interaction script. If there is a follower Pokémon present, it will be returned to its Pokeball until the NPC follower is destroyed.
Here's an example:
`setfollowernpc 3, FNPC_ALL, MyScript_Eventscript_CustomFollowerScript, PARTNER_STEVEN`
This would turn object number 3 on the current map into an NPC follower, give them access to all following behaviors, run that custom script when the player interacts with them, and adds the Steven battle partner to the follower ([more on this later](#battle-partner)).
The object ***MUST*** have an event flag or the NPC follower will not be created!
## Follower Flags
These are required to tell the game what behavior you want the NPC follower to have. They are defined in [include/constants/follower_npc.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/upcoming/include/constants/follower_npc.h). The second list of flags is the same as the first, but with shortened names to make them easier to type when scripting. The first 7 flags in the list are individual behaviors, whereas the remaining three are bundles of flags. For example, if you use `FNPC_SURF` in `setfollowernpc`, the NPC follower will be able to Surf behind the player. If you use `FNPC_ALL_WATER` instead, the NPC follower will be able to Dive and go up Waterfalls in addition to being able to Surf. Feel free to add your own custom bundles of flags to the file to meet your needs.
If the NPC doesn't have unique running frames, you should not use the `FOLLOWER_NPC_FLAG_HAS_RUNNING_FRAMES`(`FNPC_RUNNING`) flag for them, as this will cause visual glitching. If the flag is not used, the follower will simply use their regular walking animation frames, just sped up. The only objects currently in the game that have unique running frames are the player and rival characters, so the running frames flag should be used for those.
To make sure the NPC follower uses the correct animation frames, you should add an entry to `gFollowerAlternateSprites` in [include/follower_npc_alternate_sprites.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/upcoming/include/follower_npc_alternate_sprites.h). Only do this if your object has distinct animation frames for different behaviors (running, biking, surfing, etc). Follow the templates for Rival May and Rival Brendan that already exist there.
## Follower Movements
You can use the `applymovement` macro on an NPC follower by using `OBJ_EVENT_ID_NPC_FOLLOWER` for the object id. This is convenient for making the NPC follower walk off-screen before destroying them. If an NPC follower is not immediately next to the player while the controls aren't locked, it will try to take steps to get back into position as the player moves, sometimes walking through impassable areas (like through the middle of buildings).
You can also use `facefollowernpc` to make both the player and the NPC follower face each other.
> [!NOTE]
> The existing vanilla movement scripts do not take NPC followers into account. Other NPCs may walk into the follower or the follower may get left behind. If you want follower NPCs to work with these existing scripts, you will need to add your own handling for them. The `hidefollowernpc` macro can be particularly useful for this.
## Check for Follower
You can use the `checkfollowernpc` macro to check whether or not an NPC follower currently exists. It will set `VAR_RESULT` to `TRUE` if an NPC follower exists, otherwise it will be set to `FALSE`.
## Hide the Follower
The `hidefollowernpc` macro makes the NPC follower walk into the player and be hidden. The game will wait until the movement is finished before continuing with the script. There is an optional parameter that can be used to set the desired walk speed for the movement. It can be from `0` (slowest) to `3` (fastest). If a walk speed is not specified, it will default to the normal walk speed. The NPC follower will reappear the next time the player takes a step (outside of scripts).
## Destroy the Follower
The `destroyfollowernpc` macro acts similarly to `removeobject`. It removes the NPC follower object instantly and sets their flag. If you have Pokémon followers enabled, the Pokémon will reappear the next time the player takes a step.
## Battle Partner
If you assign a battle partner to the NPC follower, that partner will fight alongside the player in all trainer battles while the follower is present. This turns all battles into multi battles, whether against one opponent or two.
You can use any battle partner that has been defined in [include/constants/battle_partner.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/upcoming/include/constants/battle_partner.h). The partners' information and Pokémon teams can be set in [src/data/battle_partners.party](https://github.com/rh-hideout/pokeemerald-expansion/blob/upcoming/src/data/battle_partners.party).
To change the battle partner of an existing NPC follower, you can use the `changefollowerbattler` macro with the desired partner ID. If you change the ID to `0`, the NPC follower will not participate in any battles until you change it back to a valid partner ID.
Keep in mind that only the first 3 Pokémon in the player's party will participate in multi battles. The other three party members are temporarily replaced with the partner's Pokémon. This means the last three Pokémon in the player's party will not receive any experience points (even from the EXP Share).

View File

@ -118,7 +118,7 @@ The function that determines if a Slide should play has different function for m
+ if (IsSlideInitalizedOrPlayed(slideId))
+ return;
+
+ if (GetBattlerSide(target) == B_SIDE_OPPONENT)
+ if (!IsOnPlayerSide(target))
+ return;
+
+ InitalizeTrainerSlide(slideId);

View File

@ -0,0 +1,813 @@
# Time-Based Encounters Tutorial
## Table of Contents:
- [What is the Time-Based Encounters feature?](#what-is-the-time-based-encounters-feature)
- [Sounds rad, how do I add it to my romhack?](#sounds-rad-how-do-i-add-it-to-my-romhack)
- [I've never added one by hand, but I want to!](#ive-never-added-one-by-hand-but-i-want-to)
- [What are "supported suffixes?"](#what-are-supported-suffixes)
- [That's a lot of manual editing.](#thats-a-lot-of-manual-editing)
- [That's *still* a lot of editing.](#thats-still-a-lot-of-editing)
- [So what are the `#define` options in `overworld.h`?](#so-what-are-the-define-options-in-overworldh)
- [Examples](#examples)
## What is the Time-Based Encounters feature?
Time-Based Encounters lets you pick which Pokémon appear based on the in-game clock, per route!
Gen 2 had this feature, and Gen 4 brought it back- for instance, in Sinnoh's Route 201 you have a higher chance of catching a Bidoof than a Starly at night.
### Sounds rad, how do I add it to my romhack?
There are a couple of ways! The system is built to handle your unchanged [`wild_encounters.json`](../../src/data/wild_encounters.json) file by default, so the most basic solution is to add an encounter group by editing that (by hand or [with Porymap](https://huderlem.github.io/porymap/manual/editing-wild-encounters.html)), and then add a [supported suffix](#what-are-supported-suffixes) to the end of whatever name you give it.
> **NOTE**: if you haven't specified or added any encounters, or have the option turned off, Expansion puts them into the `TIME_MORNING` (or whatever your first time enum is set to in the `TimeOfDay` `enum` in [`rtc.h`](../../include/rtc.h)) slot to keep vanilla behavior. This means any map `"base_label"` without a [supported suffix](#what-are-supported-suffixes) is automatically set to the first time slot when `OW_TIME_OF_DAY_ENCOUNTERS` is `TRUE`. When `OW_TIME_OF_DAY_ENCOUNTERS` is `FALSE`, everything regardless of any extant suffixes gets the first time slot suffix (ie `_Morning` for `TIME_MORNING`) so it matches with the 0th index of the [`encounterTypes` array](../../include/wild_encounter.h) in `struct WildMonHeader`.
### I've never added one by hand, but I want to!
Great attitude bestie! It's very simple- all you need is to find your [`wild_encounters.json`](../../src/data/wild_encounters.json) file and open it up in your text/code editor of choice; I recommend VSCodium, but any will work.
To get started, we'll use Route 101 as an example:
```json
{
"map": "MAP_ROUTE101",
"base_label": "gRoute101",
"land_mons": {
"encounter_rate": 20,
"mons": [
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
}
]
}
},
```
That's it! That's the entire encounter group for Route 101. In other Routes or maps, you'll likely see other encounters listed; here we have only have `land_mons`, but vanilla emerald supports three more types of encounters, for a total of four:
- `land_mons`, your standard grass or cave or sand encounter.
- `water_mons`, used for surfing
- `rock_smash_mons`, for when you get jumpscared by a Geodude in Route 111 after using Rock Smash.
- `fishing_mons`, for fishing
> **NOTE**: You can also have more of these encounter types- in fact, expansion has a fifth type of encounter for the Dexnav feature called `hidden_mons`, and some people have entries for `honey_mons` and `headbutt_mons` in their personal hacks as well! This system supports those too, you just need to make sure to update your [`WildEncounters` struct](../../include/wild_encounter.h) definition. You need to keep the order consistent, so as a standard, any custom encounter types should go before `hidden_mons` but after `fishing_mons`. To use the earlier examples:
```c
struct WildEncounterTypes
{
const struct WildPokemonInfo *landMonsInfo;
const struct WildPokemonInfo *waterMonsInfo;
const struct WildPokemonInfo *rockSmashMonsInfo;
const struct WildPokemonInfo *fishingMonsInfo;
const struct WildPokemonInfo *honeyMonsInfo;
const struct WildPokemonInfo *headbuttMonsInfo;
const struct WildPokemonInfo *hiddenMonsInfo;
};
```
> You can see that the two new entries, `honeyMonsInfo` and `headbuttMonsInfo` (corresponding with `honey_mons` and `headbutt_mons`) are slotted in between `fishingMonsInfo` and `hiddenMonsInfo`. Structs in the C programming language rely on consistent placement with their members, so this is the order that every other instance of these encounter types should maintain. In my ~~expert~~ opinion, the easiest way to add these is again [with Porymap](https://huderlem.github.io/porymap/manual/editing-wild-encounters.html). Okay, take a breath, stretch, and we'll get back to the tutorial!
For the sake of simplicity, I'll show you how to add another encounter group here and pop a supported prefix on it. I want my new encounter group to:
- have a fishing table (I'm adding a fishin hole to Route 101)
- let you catch Spiky Eared Pichu, my favorite mon (not really)
- have some rock smash encounters to up the spook factor
- only occur at night
With all of these things in mind, let's craft an encounter! We'll start off by copying the one we have, called `gRoute101`.
```json
{
"map": "MAP_ROUTE101",
"base_label": "gRoute101",
"land_mons": {
"encounter_rate": 20,
"mons": [
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
}
]
}
},
{
"map": "MAP_ROUTE101",
"base_label": "gRoute101_Night",
"land_mons": {
"encounter_rate": 20,
"mons": [
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
}
]
}
},
```
Okay, we have it duplicated. We leave the value for "map": the same as the original so the game knows that both of these encounters are for Route 101. You can see I changed the name of the copy to `gRoute101_Night`; that's one bullet point down! If we enable `OW_TIME_BASED_ENCOUNTERS` in [`overworld.h`](../../include/config/overworld.h), the game will recognize this encounter group goes in the `Night` slot and will switch which group is used to generate the encounters when the in-game clock changes to `TIME_NIGHT`. Next, let's add Spiky Eared Pichu and our two new encounter tables (`fishing_mons` and `rock_smash_mons`).
```json
{
"map": "MAP_ROUTE101",
"base_label": "gRoute101_Night",
"land_mons": {
"encounter_rate": 20,
"mons": [
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_PICHU_SPIKY_EARED"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
}
]
},
"fishing_mons": {
"encounter_rate": 30,
"mons": [
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_MAGIKARP"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_MARILL"
}
]
},
"rock_smash_mons": {
"encounter_rate": 20,
"mons": [
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_GEODUDE"
}
]
}
},
```
And there we go! It has the `_Night` suffix, has Spiky Eared Pichu right up at the top of the list, has a couple of fishing encounters, and will jumpscare us with about a 20% chance every time we break a rock with rock smash. That's what the `encounter_rate` line means, by the way- the overall percentage you have of encountering *any* of the Pokémon listed.
Congrats! You've just created a brand new encounter group, set its time, and adjusted the encounters! I'd highly recommend doing this [with Porymap](https://huderlem.github.io/porymap/manual/editing-wild-encounters.html)- the interface is very useful for editing maps, including wild encounters!
### What are "supported suffixes?"
Vanilla Pokémon games usually work with 4 different times of day:
- `TIME_MORNING`
- `TIME_DAY`
- `TIME_EVENING`
- `TIME_NIGHT`
So, the "supported suffixes" are just:
- `_Morning`
- `_Day`
- `_Evening`
- `_Night`
> **NOTE**: You can add more than just these by changing the `TimeOfDay` `enum` in [`rtc.h`](../../include/rtc.h). If you'd like to do this, I'd recommend making a backup of your [`wild_encounters.json`](../../src/data/wild_encounters.json) somewhere outside your project folder, just so you can have a baseline to return to if something goes wrong. The [migration script](../../migration_scripts/add_time_based_encounters.py) makes a backup of the file ***each time it runs***, so it's essentially a one step undo button- if you plan on or think you might make lots of edits to [`wild_encounters.json`](../../src/data/wild_encounters.json), ***it is a very good idea to make a baseline backup***.
### That's a lot of manual editing.
You're so right bestie! Luckily for you, there's a python script that can help you out!
The script is at [`migration_scripts/add_time_based_encounters.py`](../../migration_scripts/add_time_based_encounters.py). It, in order:
1. Checks to make sure you're running it from the [root folder](../../) of your expansion project (specifically, wherever the project's [`Makefile`](../../Makefile) is)
2. Makes a backup of your [`wild_encounters.json`](../../src/data/wild_encounters.json) file called `wild_encounters.json.bak`
3. Runs through `wild_encounters.json` and adds dummy encounter groups for each time denomination to each group
- ie, `gRoute101` becomes `gRoute101_Morning`, `gRoute101_Day`, `gRoute101_Evening`, and `gRoute101_Night`
This script works kind of like a "template" feature- when you open it up to edit either in Porymap or a text editor, you will see the encounter groups, but they won't be filled out with encounters. This lets you add Pokémon with your own encounter rates however you want.
### That's *still* a lot of editing.
You're *still* so right bestie! Luckily for you, there's an optional argument you can add when you run the script: `--copy`.
This duplicates the encounter group's encounters as well as their labels/map group values. When you open [`wild_encounters.json`](../../src/data/wild_encounters.json) for editing either in Porymap or a text editor, you'll notice that each group (`gRoute101_Morning`, `gRoute101_Day`, `gRoute101_Evening`, and `gRoute101_Night`) now all have the same encounters as `gRoute101` did. If you only want to add a couple of Pokémon here and there for each time of day, this is probably the easier option.
> **NOTE**: the `--copy` option will use up at least an additional 9kb of ROM space. Obviously that's not much even for a GBA ROM, but it's something to keep in mind.
## So what are the `#define` options in [`overworld.h`](../../include/config/overworld.h)?
Great questie bestie!
Here's a rundown, with more information than what's in the comments at [`overworld.h`](../../include/config/overworld.h) and their default values:
```
OW_TIME_OF_DAY_ENCOUNTERS FALSE
```
- **Acceptable values**: `TRUE` or `FALSE`
- this option enables or disables the feature. You'll notice your used ROM space changing when this is enabled or disabled, as the [json->C header conversion file](../../tools/wild_encounters/wild_encounters_to_header.py) will generate the `encounterTypes` array in [`wild_encounter.h`](../../include/wild_encounter.h) with different sizes based on whether this value is `TRUE` or `FALSE`.
```
OW_TIME_OF_DAY_DISABLE_FALLBACK FALSE
```
- **Acceptable values**: `TRUE` or `FALSE`
- this option controls the behavior of the game when an encounter table isn't populated. If this is set to `TRUE`, whenever the game detects that you're in a time of day (Morning/Day/Evening/Night) on a map without any encounters for that time, you won't encounter any mons. If this is set to `FALSE`, the game will look for encounters at the time specified in the `OW_TIME_OF_DAY_FALLBACK` option below.
```
OW_TIME_OF_DAY_FALLBACK TIME_MORNING
```
- **Acceptable values**: any value from the [`TimesOfDay`](../../include/rtc.h) enum, so by default `TIME_MORNING`, `TIME_DAY`, `TIME_EVENING`, and `TIME_NIGHT`.
- this option controls which time is used when `OW_TIME_OF_DAY_DISABLE_FALLBACK` is `FALSE`. Keep in mind that if you enable `OW_TIME_OF_DAY_ENCOUNTERS` and set this to something other than `TIME_MORNING`, you should make sure that time has encounters, or you won't encounter anything.
## Examples
### Running the [migration script](../../migration_scripts/add_time_based_encounters.py) without the `--copy` option
**Make sure you run this from the [root folder](../../) of your project!**
```
python3 migration_scripts/add_time_based_encounters.py
```
#### Result:
```json
"encounters": [
{
"map": "MAP_ROUTE101",
"base_label": "gRoute101_Morning",
"land_mons": {
"encounter_rate": 20,
"mons": [
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
}
]
}
},
{
"map": "MAP_ROUTE101",
"base_label": "gRoute101_Day"
},
{
"map": "MAP_ROUTE101",
"base_label": "gRoute101_Evening"
},
{
"map": "MAP_ROUTE101",
"base_label": "gRoute101_Night"
},
]
```
As you can see, the names change, but the encounters aren't touched, so you're free to add your own, piecemeal style. If you don't have any encounters for a map and time, the game will use `OW_TIME_OF_DAY_FALLBACK` *if* `OW_TIME_OF_DAY_DISABLE_FALLBACK` is `FALSE`; otherwise, you won't encounter anything.
### Running the [migration script](../../migration_scripts/add_time_based_encounters.py) with the `--copy` option
**Make sure you run this from the [root folder](../../) of your project!**
```
python3 migration_scripts/add_time_based_encounters.py --copy
```
#### Result:
```json
"encounters": [
{
"map": "MAP_ROUTE101",
"base_label": "gRoute101_Morning",
"land_mons": {
"encounter_rate": 20,
"mons": [
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
}
]
}
},
{
"map": "MAP_ROUTE101",
"base_label": "gRoute101_Day",
"land_mons": {
"encounter_rate": 20,
"mons": [
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
}
]
}
},
{
"map": "MAP_ROUTE101",
"base_label": "gRoute101_Evening",
"land_mons": {
"encounter_rate": 20,
"mons": [
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
}
]
}
},
{
"map": "MAP_ROUTE101",
"base_label": "gRoute101_Night",
"land_mons": {
"encounter_rate": 20,
"mons": [
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_WURMPLE"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_POOCHYENA"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 2,
"max_level": 2,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
},
{
"min_level": 3,
"max_level": 3,
"species": "SPECIES_ZIGZAGOON"
}
]
}
},
]
```
As you can see, the group `gRoute101` and all its encounters were copied into groups that correspond with the four vanilla times of day (Morning/Day/Evening/Night).

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 255
246 189 49
246 172 41
238 156 32
222 131 24
205 115 8
246 172 41
246 172 41
246 172 41
246 172 41
167 81 31
139 74 49
123 65 32
98 49 32
82 32 16
74 24 8

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 255
129 196 237
152 208 243
174 221 250
240 186 88
232 144 39
152 208 243
152 208 243
255 255 255
255 241 188
212 111 53
227 148 56
197 101 18
163 70 36
128 57 35
113 41 18

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 255
38 17 60
22 29 82
20 43 90
91 97 155
47 50 120
255 255 255
243 237 195
22 29 82
22 29 82
43 29 98
49 25 82
40 5 57
53 41 103
58 65 118
27 16 70

View File

@ -1,19 +0,0 @@
JASC-PAL
0100
16
0 0 0
246 230 180
255 222 139
255 230 123
255 222 106
255 213 98
255 197 57
255 180 32
255 172 8
255 156 8
230 131 8
222 123 8
205 106 8
205 90 8
197 74 8
189 57 8

View File

@ -1,19 +0,0 @@
JASC-PAL
0100
16
0 0 0
211 216 222
198 208 221
184 199 218
170 191 215
156 181 212
142 172 207
128 162 203
117 154 198
104 147 199
101 141 189
89 137 194
82 127 179
77 128 190
63 117 184
52 106 169

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -1,19 +0,0 @@
JASC-PAL
0100
16
0 0 0
139 90 222
131 65 230
106 41 230
98 32 230
98 16 255
65 8 255
49 8 205
41 8 180
24 0 172
24 0 156
32 0 148
32 0 131
32 0 115
24 0 106
24 0 98

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
110 198 165
64 61 42
77 73 50
85 81 58
100 94 66
111 105 75
119 112 77
140 131 92
154 145 103
171 159 111
186 174 123
197 183 128
209 195 139
224 209 146
234 219 155
249 232 161

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
106 202 166
58 54 31
67 62 33
96 89 53
110 102 57
121 111 67
128 119 66
156 143 82
166 155 96
185 169 100
199 183 112
211 192 113
223 203 123
237 218 129
247 227 137
255 237 147

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
104 203 168
19 48 64
35 87 115
58 132 140
69 156 166
77 193 254
106 239 254
27 68 89
64 22 19
115 39 34
166 57 49
191 66 57
222 77 67
0 0 0
0 0 0
0 0 0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -85,12 +85,12 @@ struct DisableStruct
s8 stockpileBeforeSpDef;
u8 substituteHP;
u8 encoredMovePos;
u8 disableTimer:4;
u8 encoreTimer:4;
u8 perishSongTimer:4;
u8 rolloutTimer:4;
u8 rolloutTimerStartValue:4;
u8 tauntTimer:4;
u16 disableTimer;
u16 encoreTimer;
u16 perishSongTimer;
u16 rolloutTimer;
u16 rolloutTimerStartValue;
u16 tauntTimer;
u8 furyCutterCounter;
u8 battlerPreventingEscape;
u8 battlerWithSureHit;
@ -99,16 +99,16 @@ struct DisableStruct
u8 chargeTimer:4;
u8 rechargeTimer;
u8 autotomizeCount;
u8 slowStartTimer;
u8 embargoTimer;
u8 magnetRiseTimer;
u8 telekinesisTimer;
u8 healBlockTimer;
u8 laserFocusTimer;
u8 throatChopTimer;
u16 slowStartTimer;
u16 embargoTimer;
u16 magnetRiseTimer;
u16 telekinesisTimer;
u16 healBlockTimer;
u16 laserFocusTimer;
u16 throatChopTimer;
u8 wrapTurns;
u8 syrupBombTimer;
u8 tormentTimer:4; // used for G-Max Meltdown
u16 syrupBombTimer;
u16 tormentTimer; // used for G-Max Meltdown
u8 usedMoves:4;
u8 truantCounter:1;
u8 truantSwitchInHack:1;
@ -139,11 +139,7 @@ struct DisableStruct
// Fully Cleared each turn after end turn effects are done. A few things are cleared before end turn effects
struct ProtectStruct
{
u32 protected:1;
u32 spikyShielded:1;
u32 kingsShielded:1;
u32 banefulBunkered:1;
u32 obstructed:1;
u32 protected:7; // 126 protect options
u32 endured:1;
u32 noValidMoves:1;
u32 helpingHand:1;
@ -151,7 +147,6 @@ struct ProtectStruct
u32 stealMove:1;
u32 nonVolatileStatusImmobility:1;
u32 confusionSelfDmg:1;
u32 targetAffected:1;
u32 chargingTurn:1;
u32 fleeType:2; // 0: Normal, 1: FLEE_ITEM, 2: FLEE_ABILITY
u32 unableToUseMove:1; // Not to be confused with HITMARKER_UNABLE_TO_USE_MOVE (It is questionable though if there is a difference. Needs further research)
@ -161,7 +156,7 @@ struct ProtectStruct
u32 statRaised:1;
u32 usedCustapBerry:1; // also quick claw
u32 touchedProtectLike:1;
u32 unused:9;
u32 unused:8;
// End of 32-bit bitfield
u16 disableEjectPack:1;
u16 statFell:1;
@ -170,17 +165,14 @@ struct ProtectStruct
u16 beakBlastCharge:1;
u16 quash:1;
u16 shellTrap:1;
u16 maxGuarded:1;
u16 silkTrapped:1;
u16 burningBulwarked:1;
u16 eatMirrorHerb:1;
u16 activateOpportunist:2; // 2 - to copy stats. 1 - stats copied (do not repeat). 0 - no stats to copy
u16 usedAllySwitch:1;
u16 lashOutAffected:1;
u16 padding:1;
u16 padding:4;
// End of 16-bit bitfield
u32 physicalDmg;
u32 specialDmg;
u16 physicalDmg;
u16 specialDmg;
u8 physicalBattlerId;
u8 specialBattlerId;
};
@ -190,24 +182,22 @@ struct SpecialStatus
{
s32 physicalDmg;
s32 specialDmg;
u8 physicalBattlerId;
u8 specialBattlerId;
u8 changedStatsBattlerId; // Battler that was responsible for the latest stat change. Can be self.
u8 statLowered:1;
u8 lightningRodRedirected:1;
u8 restoredBattlerSprite: 1;
u8 faintedHasReplacement:1;
u8 focusBanded:1;
u8 focusSashed:1;
u8 emergencyExited:1;
u8 preventLifeOrbDamage:1; // So that Life Orb doesn't activate various effects.
u8 afterYou:1;
// End of byte
u8 sturdied:1;
u8 enduredDamage:1;
u8 stormDrainRedirected:1;
// End of byte
u8 switchInAbilityDone:1;
u8 switchInItemDone:1;
u8 instructedChosenTarget:3;
u8 berryReduced:1;
u8 announceNeutralizingGas:1; // See Cmd_switchineffects
u8 neutralizingGasRemoved:1; // See VARIOUS_TRY_END_NEUTRALIZING_GAS
// End of byte
u8 gemParam;
// End of byte
@ -215,29 +205,22 @@ struct SpecialStatus
u8 rototillerAffected:1; // to be affected by rototiller
u8 parentalBondState:2;
u8 multiHitOn:1;
u8 announceNeutralizingGas:1; // See Cmd_switchineffects
u8 neutralizingGasRemoved:1; // See VARIOUS_TRY_END_NEUTRALIZING_GAS
u8 affectionEndured:1;
// End of byte
u8 dancerUsedMove:1;
u8 dancerOriginalTarget:3;
u8 distortedTypeMatchups:1;
u8 teraShellAbilityDone:1;
u8 criticalHit:1;
u8 enduredDamage:1;
// End of byte
u8 dancerUsedMove:1;
u8 dancerOriginalTarget:3;
u8 unused:4;
// End of byte
};
struct SideTimer
{
u16 reflectTimer;
u8 reflectBattlerId;
u16 lightscreenTimer;
u8 lightscreenBattlerId;
u16 mistTimer;
u8 mistBattlerId;
u16 safeguardTimer;
u8 safeguardBattlerId;
u16 spikesAmount; // debug menu complains. might be better to solve there instead if possible
u16 toxicSpikesAmount;
u16 stealthRockAmount;
@ -245,11 +228,8 @@ struct SideTimer
u8 stickyWebBattlerId;
u8 stickyWebBattlerSide; // Used for Court Change
u16 auroraVeilTimer;
u8 auroraVeilBattlerId;
u16 tailwindTimer;
u8 tailwindBattlerId;
u16 luckyChantTimer;
u8 luckyChantBattlerId;
u16 steelsurgeAmount;
// Timers below this point are not swapped by Court Change
u16 followmeTimer;
@ -277,7 +257,7 @@ struct FieldTimer
struct WishFutureKnock
{
u8 futureSightCounter[MAX_BATTLERS_COUNT];
u16 futureSightCounter[MAX_BATTLERS_COUNT];
u8 futureSightBattlerIndex[MAX_BATTLERS_COUNT];
u8 futureSightPartyIndex[MAX_BATTLERS_COUNT];
u16 futureSightMove[MAX_BATTLERS_COUNT];
@ -303,16 +283,17 @@ struct AiPartyMon
u16 item;
u16 heldEffect;
u16 ability;
u16 gender;
u16 level;
u16 moves[MAX_MON_MOVES];
u32 status;
bool8 isFainted;
bool8 wasSentInBattle;
u8 switchInCount; // Counts how many times this Pokemon has been sent out or switched into in a battle.
u8 gender:2;
u8 isFainted:1;
u8 wasSentInBattle:1;
u8 padding:4;
};
struct AIPartyData // Opposing battlers - party mons.
struct AiPartyData // Opposing battlers - party mons.
{
struct AiPartyMon mons[NUM_BATTLE_SIDES][PARTY_SIZE]; // 2 parties(player, opponent). Used to save information on opposing party.
u8 count[NUM_BATTLE_SIDES];
@ -326,8 +307,9 @@ struct SwitchinCandidate
struct SimulatedDamage
{
s32 expected;
s32 minimum;
u16 minimum;
u16 median;
u16 maximum;
};
// Ai Data used when deciding which move to use, computed only once before each turn's start.
@ -351,22 +333,24 @@ struct AiLogicData
u8 weatherHasEffect:1; // The same as HasWeatherEffect(). Stored here, so it's called only once.
u8 ejectButtonSwitch:1; // Tracks whether current switch out was from Eject Button
u8 ejectPackSwitch:1; // Tracks whether current switch out was from Eject Pack
u8 predictingSwitch:1; // Determines whether AI will use predictions this turn or not
u8 aiSwitchPredictionInProgress:1; // Tracks whether the AI is in the middle of running prediction calculations
u8 padding:3;
u8 predictingSwitch:1; // Determines whether AI will use switch predictions this turn or not
u8 predictingMove:1; // Determines whether AI will use move predictions this turn or not
u8 aiPredictionInProgress:1; // Tracks whether the AI is in the middle of running prediction calculations
u8 padding:2;
u8 shouldSwitch; // Stores result of ShouldSwitch, which decides whether a mon should be switched out
u8 aiCalcInProgress:1;
u8 battlerDoingPrediction; // Stores which battler is currently running its prediction calcs
u16 predictedMove[MAX_BATTLERS_COUNT];
};
struct AI_ThinkingStruct
struct AiThinkingStruct
{
u8 aiState;
u8 movesetIndex;
u16 moveConsidered;
s32 score[MAX_MON_MOVES];
u32 funcResult;
u32 aiFlags[MAX_BATTLERS_COUNT];
u64 aiFlags[MAX_BATTLERS_COUNT];
u8 aiAction;
u8 aiLogicId;
struct AI_SavedBattleMon saved[MAX_BATTLERS_COUNT];
@ -401,6 +385,8 @@ struct BattleCallbacksStack
struct StatsArray
{
u16 stats[NUM_STATS];
u16 level:15;
u16 learnMultipleMoves:1;
};
struct BattleResources
@ -409,20 +395,11 @@ struct BattleResources
struct BattleScriptsStack *battleScriptsStack;
struct BattleCallbacksStack *battleCallbackStack;
struct StatsArray *beforeLvlUp;
struct AI_ThinkingStruct *ai;
struct AiLogicData *aiData;
struct AIPartyData *aiParty;
struct BattleHistory *battleHistory;
u8 bufferA[MAX_BATTLERS_COUNT][0x200];
u8 bufferB[MAX_BATTLERS_COUNT][0x200];
u8 transferBuffer[0x100];
};
#define AI_THINKING_STRUCT ((struct AI_ThinkingStruct *)(gBattleResources->ai))
#define AI_DATA ((struct AiLogicData *)(gBattleResources->aiData))
#define AI_PARTY ((struct AIPartyData *)(gBattleResources->aiParty))
#define BATTLE_HISTORY ((struct BattleHistory *)(gBattleResources->battleHistory))
struct BattleResults
{
u8 playerFaintCounter; // 0x0
@ -542,12 +519,15 @@ struct LinkBattlerHeader
struct BattleEnigmaBerry battleEnigmaBerry;
};
enum IllusionState {
ILLUSION_NOT_SET,
ILLUSION_OFF,
ILLUSION_ON
};
struct Illusion
{
u8 on;
u8 set;
u8 broken;
u8 partyId;
enum IllusionState state;
struct Pokemon *mon;
};
@ -562,7 +542,7 @@ struct ZMoveData
struct DynamaxData
{
u8 dynamaxTurns[MAX_BATTLERS_COUNT];
u16 dynamaxTurns[MAX_BATTLERS_COUNT];
u16 baseMoves[MAX_BATTLERS_COUNT]; // base move of Max Move
u16 lastUsedBaseMove;
};
@ -589,36 +569,12 @@ struct BattleVideo {
rng_value_t rngSeed;
};
enum BattleIntroStates
{
BATTLE_INTRO_STATE_GET_MON_DATA,
BATTLE_INTRO_STATE_LOOP_BATTLER_DATA,
BATTLE_INTRO_STATE_PREPARE_BG_SLIDE,
BATTLE_INTRO_STATE_WAIT_FOR_BG_SLIDE,
BATTLE_INTRO_STATE_DRAW_SPRITES,
BATTLE_INTRO_STATE_DRAW_PARTY_SUMMARY,
BATTLE_INTRO_STATE_WAIT_FOR_PARTY_SUMMARY,
BATTLE_INTRO_STATE_INTRO_TEXT,
BATTLE_INTRO_STATE_WAIT_FOR_INTRO_TEXT,
BATTLE_INTRO_STATE_TRAINER_SEND_OUT_TEXT,
BATTLE_INTRO_STATE_WAIT_FOR_TRAINER_SEND_OUT_TEXT,
BATTLE_INTRO_STATE_TRAINER_1_SEND_OUT_ANIM,
BATTLE_INTRO_STATE_TRAINER_2_SEND_OUT_ANIM,
BATTLE_INTRO_STATE_WAIT_FOR_TRAINER_2_SEND_OUT_ANIM,
BATTLE_INTRO_STATE_WAIT_FOR_WILD_BATTLE_TEXT,
BATTLE_INTRO_STATE_PRINT_PLAYER_SEND_OUT_TEXT,
BATTLE_INTRO_STATE_WAIT_FOR_PLAYER_SEND_OUT_TEXT,
BATTLE_INTRO_STATE_PRINT_PLAYER_1_SEND_OUT_TEXT,
BATTLE_INTRO_STATE_PRINT_PLAYER_2_SEND_OUT_TEXT,
BATTLE_INTRO_STATE_SET_DEX_AND_BATTLE_VARS
};
struct BattlerState
{
u8 targetsDone[MAX_BATTLERS_COUNT];
u32 commandingDondozo:1;
u32 absentBattlerFlags:1;
u32 absent:1;
u32 focusPunchBattlers:1;
u32 multipleSwitchInBattlers:1;
u32 alreadyStatusedMoveAttempt:1; // For example when using Thunder Wave on an already paralyzed Pokémon.
@ -631,17 +587,30 @@ struct BattlerState
u32 usedMicleBerry:1;
u32 pursuitTarget:1;
u32 stompingTantrumTimer:2;
u32 canPickupItem:1;
u32 padding:16;
// End of Word
};
struct PartyState
{
u32 intrepidSwordBoost:1;
u32 dauntlessShieldBoost:1;
u32 ateBerry:1;
u32 battleBondBoost:1;
u32 transformZeroToHero:1;
u32 supersweetSyrup:1;
u32 padding:26;
};
// Cleared at the beginning of the battle. Fields need to be cleared when needed manually otherwise.
struct BattleStruct
{
struct BattlerState battlerState[MAX_BATTLERS_COUNT];
u8 turnEffectsTracker;
struct PartyState partyState[NUM_BATTLE_SIDES][PARTY_SIZE];
u8 eventBlockCounter;
u8 turnEffectsBattlerId;
u8 turnCountersTracker;
u8 endTurnEventsCounter;
u16 wrappedMove[MAX_BATTLERS_COUNT];
u16 moveTarget[MAX_BATTLERS_COUNT];
u32 expShareExpValue;
@ -681,7 +650,6 @@ struct BattleStruct
u8 stateIdAfterSelScript[MAX_BATTLERS_COUNT];
u8 prevSelectedPartySlot;
u8 stringMoveType;
u8 absentBattlerFlags;
u8 palaceFlags; // First 4 bits are "is <= 50% HP and not asleep" for each battler, last 4 bits are selected moves to pass to AI
u8 field_93; // related to choosing pokemon?
u8 wallyBattleState;
@ -704,7 +672,6 @@ struct BattleStruct
u16 chosenItem[MAX_BATTLERS_COUNT];
u16 choicedMove[MAX_BATTLERS_COUNT];
u16 changedItems[MAX_BATTLERS_COUNT];
u8 canPickupItem;
u8 switchInBattlerCounter;
u8 arenaTurnCounter;
u8 turnSideTracker;
@ -713,18 +680,16 @@ struct BattleStruct
struct LinkBattlerHeader linkBattlerHeader;
struct BattleVideo battleVideo;
} multiBuffer;
u8 wishPerishSongState;
u8 wishPerishSongBattlerId;
u8 startingStatus:6; // status to apply at battle start. defined in constants/battle.h
u8 startingStatusDone:1;
u8 terrainDone:1;
u8 overworldWeatherDone:1;
u8 obedienceResult:3;
u8 unused:3;
u8 isAtkCancelerForCalledMove:1; // Certain cases in atk canceler should only be checked once, when the original move is called, however others need to be checked the twice.
u8 friskedAbility:1; // If identifies two mons, show the ability pop-up only once.
u8 fickleBeamBoosted:1;
u8 poisonPuppeteerConfusion:1;
u8 startingStatusTimer;
u16 startingStatusTimer;
u8 atkCancellerTracker;
struct BattleTvMovePoints tvMovePoints;
struct BattleTv tv;
@ -749,19 +714,14 @@ struct BattleStruct
struct BattleGimmickData gimmick;
const u8 *trainerSlideMsg;
enum BattleIntroStates introState:8;
u8 ateBerry[NUM_BATTLE_SIDES]; // array id determined by side, each party pokemon as bit
u8 stolenStats[NUM_BATTLE_STATS]; // hp byte is used for which stats to raise, other inform about by how many stages
u8 lastMoveTarget[MAX_BATTLERS_COUNT]; // The last target on which each mon used a move, for the sake of Instruct
u16 tracedAbility[MAX_BATTLERS_COUNT];
u16 hpBefore[MAX_BATTLERS_COUNT]; // Hp of battlers before using a move. For Berserk and Anger Shell.
struct Illusion illusion[MAX_BATTLERS_COUNT];
s32 aiFinalScore[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // AI, target, moves to make debugging easier
u8 aiMoveOrAction[MAX_BATTLERS_COUNT];
u8 aiChosenTarget[MAX_BATTLERS_COUNT];
u8 soulheartBattlerId;
u8 friskedBattler; // Frisk needs to identify 2 battlers in double battles.
u8 sameMoveTurns[MAX_BATTLERS_COUNT]; // For Metronome, number of times the same moves has been SUCCESFULLY used.
u16 moveEffect2; // For Knock Off
u16 changedSpecies[NUM_BATTLE_SIDES][PARTY_SIZE]; // For forms when multiple mons can change into the same pokemon.
u8 quickClawBattlerId;
struct LostItem itemLost[NUM_BATTLE_SIDES][PARTY_SIZE]; // Pokemon that had items consumed or stolen (two bytes per party member per side)
@ -783,7 +743,6 @@ struct BattleStruct
u8 pledgeMove:1;
u8 effectsBeforeUsingMoveDone:1; // Mega Evo and Focus Punch/Shell Trap effects.
u8 spriteIgnore0Hp:1;
u8 battleBondTransformed[NUM_BATTLE_SIDES]; // Bitfield for each party.
u8 bonusCritStages[MAX_BATTLERS_COUNT]; // G-Max Chi Strike boosts crit stages of allies.
u8 itemPartyIndex[MAX_BATTLERS_COUNT];
u8 itemMoveIndex[MAX_BATTLERS_COUNT];
@ -792,11 +751,7 @@ struct BattleStruct
s32 aiDelayFrames; // Number of frames it took to choose an action.
s32 aiDelayCycles; // Number of cycles it took to choose an action.
u8 timesGotHit[NUM_BATTLE_SIDES][PARTY_SIZE];
u8 transformZeroToHero[NUM_BATTLE_SIDES];
u8 stickySyrupdBy[MAX_BATTLERS_COUNT];
u8 intrepidSwordBoost[NUM_BATTLE_SIDES];
u8 dauntlessShieldBoost[NUM_BATTLE_SIDES];
u8 supersweetSyrup[NUM_BATTLE_SIDES];
u8 supremeOverlordCounter[MAX_BATTLERS_COUNT];
u8 shellSideArmCategory[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT];
u8 speedTieBreaks; // MAX_BATTLERS_COUNT! values.
@ -823,7 +778,6 @@ struct BattleStruct
u8 numSpreadTargets:2;
u8 bypassMoldBreakerChecks:1; // for ABILITYEFFECT_IMMUNITY
u8 noTargetPresent:1;
u8 usedMicleBerry;
struct MessageStatus slideMessageStatus;
u8 trainerSlideSpriteIds[MAX_BATTLERS_COUNT];
u16 opponentMonCanTera:6;
@ -831,6 +785,17 @@ struct BattleStruct
u16 padding:4;
};
struct AiBattleData
{
s32 finalScore[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // AI, target, moves to make debugging easier
u8 playerStallMons[PARTY_SIZE];
u8 chosenMoveIndex[MAX_BATTLERS_COUNT];
u8 chosenTarget[MAX_BATTLERS_COUNT];
u8 actionFlee:1;
u8 choiceWatch:1;
u8 padding:6;
};
// The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider,
// and 1 flag per battler to indicate whether the battler is awake and at <= 50% HP (which affects move choice).
// The assert below is to ensure palaceFlags is large enough to store these flags without overlap.
@ -855,11 +820,6 @@ static inline bool32 IsBattleMoveStatus(u32 move)
return GetMoveCategory(move) == DAMAGE_CATEGORY_STATUS;
}
static inline bool32 IsBattleMoveRecoil(u32 move)
{
return GetMoveRecoil(move) > 0 || GetMoveEffect(move) == EFFECT_RECOIL_IF_MISS;
}
/* Checks if 'battler' is any of the types.
* Passing multiple types is more efficient than calling this multiple
* times with one type because it shares the 'GetBattlerTypes' result. */
@ -898,14 +858,6 @@ static inline bool32 IsBattleMoveRecoil(u32 move)
gBattleMons[battler].types[2] = TYPE_MYSTERY; \
}
#define IS_BATTLER_PROTECTED(battler)(gProtectStructs[battler].protected \
|| gProtectStructs[battler].spikyShielded \
|| gProtectStructs[battler].kingsShielded \
|| gProtectStructs[battler].banefulBunkered \
|| gProtectStructs[battler].burningBulwarked \
|| gProtectStructs[battler].obstructed \
|| gProtectStructs[battler].silkTrapped)
#define GET_STAT_BUFF_ID(n) ((n & 7)) // first three bits 0x1, 0x2, 0x4
#define GET_STAT_BUFF_VALUE_WITH_SIGN(n) ((n & 0xF8))
#define GET_STAT_BUFF_VALUE(n) (((n >> 3) & 0xF)) // 0x8, 0x10, 0x20, 0x40
@ -922,11 +874,11 @@ static inline bool32 IsBattleMoveRecoil(u32 move)
// in include/constants/battle_script_commands.h
struct BattleScripting
{
s32 painSplitHp;
s32 unused1;
s32 bideDmg;
u8 multihitString[6];
bool8 expOnCatch;
u8 unused;
u8 unused2;
u8 animArg1;
u8 animArg2;
u16 savedStringId;
@ -1142,6 +1094,11 @@ extern u8 gSentPokesToOpponent[2];
extern struct BattleEnigmaBerry gEnigmaBerries[MAX_BATTLERS_COUNT];
extern struct BattleScripting gBattleScripting;
extern struct BattleStruct *gBattleStruct;
extern struct AiBattleData *gAiBattleData;
extern struct AiThinkingStruct *gAiThinkingStruct;
extern struct AiLogicData *gAiLogicData;
extern struct AiPartyData *gAiPartyData;
extern struct BattleHistory *gBattleHistory;
extern u8 *gLinkBattleSendBuffer;
extern u8 *gLinkBattleRecvBuffer;
extern struct BattleResources *gBattleResources;
@ -1233,9 +1190,14 @@ static inline u32 GetBattlerSide(u32 battler)
return GetBattlerPosition(battler) & BIT_SIDE;
}
static inline u32 IsOnPlayerSide(u32 battler)
{
return GetBattlerSide(battler) == B_SIDE_PLAYER;
}
static inline bool32 IsBattlerAlly(u32 battlerAtk, u32 battlerDef)
{
return (GetBattlerSide(battlerAtk) == GetBattlerSide(battlerDef));
return GetBattlerSide(battlerAtk) == GetBattlerSide(battlerDef);
}
static inline u32 GetOpposingSideBattler(u32 battler)
@ -1243,15 +1205,15 @@ static inline u32 GetOpposingSideBattler(u32 battler)
return GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerSide(battler)));
}
static inline struct Pokemon* GetPartyBattlerData(u32 battler)
static inline struct Pokemon* GetBattlerMon(u32 battler)
{
u32 index = gBattlerPartyIndexes[battler];
return (GetBattlerSide(battler) == B_SIDE_OPPONENT) ? &gEnemyParty[index] : &gPlayerParty[index];
return !IsOnPlayerSide(battler) ? &gEnemyParty[index] : &gPlayerParty[index];
}
static inline struct Pokemon *GetSideParty(u32 side)
{
return (side == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
return side == B_SIDE_PLAYER ? gPlayerParty : gEnemyParty;
}
static inline struct Pokemon *GetBattlerParty(u32 battler)
@ -1283,12 +1245,4 @@ static inline bool32 IsBattlerInvalidForSpreadMove(u32 battlerAtk, u32 battlerDe
|| (battlerDef == BATTLE_PARTNER(battlerAtk) && (moveTarget == MOVE_TARGET_BOTH));
}
static inline bool32 IsBattlerSideProtected(u32 battler)
{
return gSideStatuses[GetBattlerSide(battler)] & (SIDE_STATUS_WIDE_GUARD
| SIDE_STATUS_QUICK_GUARD
| SIDE_STATUS_CRAFTY_SHIELD
| SIDE_STATUS_MAT_BLOCK);
}
#endif // GUARD_BATTLE_H

View File

@ -6,41 +6,40 @@ typedef s32 (*AiScoreFunc)(u32, u32, u32, s32);
#define UNKNOWN_NO_OF_HITS UINT32_MAX
// return vals for BattleAI_ChooseMoveOrAction
// 0 - 3 are move idx
#define AI_CHOICE_FLEE 4
#define AI_CHOICE_WATCH 5
// for AI_WhoStrikesFirst
#define AI_IS_FASTER 1
#define AI_IS_SLOWER -1
// for stat increasing / decreasing scores
#define STAT_CHANGE_ATK 0
#define STAT_CHANGE_DEF 1
#define STAT_CHANGE_SPEED 2
#define STAT_CHANGE_SPATK 3
#define STAT_CHANGE_SPDEF 4
#define STAT_CHANGE_ATK_2 5
#define STAT_CHANGE_DEF_2 6
#define STAT_CHANGE_SPEED_2 7
#define STAT_CHANGE_SPATK_2 8
#define STAT_CHANGE_SPDEF_2 9
#define STAT_CHANGE_ACC 10
#define STAT_CHANGE_EVASION 11
enum StatChange
{
STAT_CHANGE_ATK,
STAT_CHANGE_DEF,
STAT_CHANGE_SPEED,
STAT_CHANGE_SPATK,
STAT_CHANGE_SPDEF,
STAT_CHANGE_ATK_2,
STAT_CHANGE_DEF_2,
STAT_CHANGE_SPEED_2,
STAT_CHANGE_SPATK_2,
STAT_CHANGE_SPDEF_2,
STAT_CHANGE_ACC,
STAT_CHANGE_EVASION
};
#define BEST_DAMAGE_MOVE 1 // Move with the most amount of hits with the best accuracy/effect
#define POWERFUL_STATUS_MOVE 10 // Moves with this score will be chosen over a move that faints target
#define NO_DAMAGE_OR_FAILS -20 // Move fails or does no damage
// Scores given in AI_CalcMoveEffectScore and AI_CalcHoldEffectMoveScore
#define NO_INCREASE 0
#define WEAK_EFFECT 1
#define DECENT_EFFECT 2
#define GOOD_EFFECT 3
#define BEST_EFFECT 4
enum AIScore
{
NO_INCREASE = 0,
WEAK_EFFECT = 1,
DECENT_EFFECT = 2,
GOOD_EFFECT = 3,
BEST_EFFECT = 4
};
// AI_TryToFaint
#define FAST_KILL 6 // AI is faster and faints target
@ -61,7 +60,7 @@ typedef s32 (*AiScoreFunc)(u32, u32, u32, s32);
{ \
TestRunner_Battle_AISetScore(__FILE__, __LINE__, battler, movesetIndex, val); \
} \
AI_THINKING_STRUCT->score[movesetIndex] = val; \
gAiThinkingStruct->score[movesetIndex] = val; \
} while (0) \
#define ADJUST_SCORE(val) \
@ -69,7 +68,7 @@ typedef s32 (*AiScoreFunc)(u32, u32, u32, s32);
{ \
if (TESTING) \
{ \
TestRunner_Battle_AIAdjustScore(__FILE__, __LINE__, battlerAtk, AI_THINKING_STRUCT->movesetIndex, val); \
TestRunner_Battle_AIAdjustScore(__FILE__, __LINE__, battlerAtk, gAiThinkingStruct->movesetIndex, val); \
} \
score += val; \
} while (0) \
@ -79,7 +78,7 @@ typedef s32 (*AiScoreFunc)(u32, u32, u32, s32);
{ \
if (TESTING) \
{ \
TestRunner_Battle_AIAdjustScore(__FILE__, __LINE__, battlerAtk, AI_THINKING_STRUCT->movesetIndex, val); \
TestRunner_Battle_AIAdjustScore(__FILE__, __LINE__, battlerAtk, gAiThinkingStruct->movesetIndex, val); \
} \
score += val; \
return score; \
@ -90,7 +89,7 @@ typedef s32 (*AiScoreFunc)(u32, u32, u32, s32);
{ \
if (TESTING) \
{ \
TestRunner_Battle_AIAdjustScore(__FILE__, __LINE__, battlerAtk, AI_THINKING_STRUCT->movesetIndex, val); \
TestRunner_Battle_AIAdjustScore(__FILE__, __LINE__, battlerAtk, gAiThinkingStruct->movesetIndex, val); \
} \
(*score) += val; \
} while (0) \
@ -110,7 +109,8 @@ typedef s32 (*AiScoreFunc)(u32, u32, u32, s32);
void BattleAI_SetupItems(void);
void BattleAI_SetupFlags(void);
void BattleAI_SetupAIData(u8 defaultScoreMoves, u32 battler);
u32 BattleAI_ChooseMoveOrAction(u32 battler);
void ComputeBattlerDecisions(u32 battler);
u32 BattleAI_ChooseMoveIndex(u32 battler);
void Ai_InitPartyStruct(void);
void Ai_UpdateSwitchInData(u32 battler);
void Ai_UpdateFaintData(u32 battler);

View File

@ -32,6 +32,7 @@ enum ShouldSwitchScenario
SHOULD_SWITCH_CHOICE_LOCKED,
SHOULD_SWITCH_ATTACKING_STAT_MINUS_TWO,
SHOULD_SWITCH_ATTACKING_STAT_MINUS_THREE_PLUS,
SHOULD_SWITCH_ALL_SCORES_BAD,
};
enum SwitchType
@ -45,5 +46,6 @@ void AI_TrySwitchOrUseItem(u32 battler);
u32 GetMostSuitableMonToSwitchInto(u32 battler, enum SwitchType switchType);
bool32 ShouldSwitch(u32 battler);
bool32 IsMonGrounded(u16 heldItemEffect, u32 ability, u8 type1, u8 type2);
void ModifySwitchAfterMoveScoring(u32 battler);
#endif // GUARD_BATTLE_AI_SWITCH_ITEMS_H

View File

@ -1,6 +1,8 @@
#ifndef GUARD_BATTLE_AI_UTIL_H
#define GUARD_BATTLE_AI_UTIL_H
#include "battle_ai_main.h"
#define FOE(battler) ((BATTLE_OPPOSITE(battler)) & BIT_SIDE)
// Roll boundaries used by AI when scoring. Doesn't affect actual damage dealt.
@ -15,6 +17,12 @@ enum DamageRollType
DMG_ROLL_HIGHEST,
};
enum DamageCalcContext
{
AI_DEFENDING,
AI_ATTACKING,
};
enum AIPivot
{
DONT_PIVOT,
@ -30,10 +38,19 @@ enum WeatherState
WEATHER_INACTIVE_AND_BLOCKED,
};
static inline bool32 IsMoveUnusable(u32 moveIndex, u32 move, u32 moveLimitations)
{
return move == MOVE_NONE
|| move == MOVE_UNAVAILABLE
|| moveLimitations & 1u << moveIndex;
}
typedef bool32 (*MoveFlag)(u32 move);
bool32 AI_IsFaster(u32 battlerAi, u32 battlerDef, u32 move);
bool32 AI_IsSlower(u32 battlerAi, u32 battlerDef, u32 move);
bool32 AI_RandLessThan(u32 val);
u32 GetDmgRollType(u32 battlerAtk);
u32 AI_GetDamage(u32 battlerAtk, u32 battlerDef, u32 moveIndex, enum DamageCalcContext calcContext, struct AiLogicData *aiData);
bool32 IsAiVsAiBattle(void);
bool32 BattlerHasAi(u32 battlerId);
bool32 IsAiBattlerAware(u32 battlerId);
@ -54,21 +71,23 @@ u32 GetTotalBaseStat(u32 species);
bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler);
bool32 AI_BattlerAtMaxHp(u32 battler);
u32 GetHealthPercentage(u32 battler);
bool32 IsBattlerTrapped(u32 battler, bool32 switching);
bool32 AI_CanBattlerEscape(u32 battler);
bool32 IsBattlerTrapped(u32 battlerAtk, u32 battlerDef);
s32 AI_WhoStrikesFirst(u32 battlerAI, u32 battler2, u32 moveConsidered);
bool32 CanTargetFaintAi(u32 battlerDef, u32 battlerAtk);
u32 NoOfHitsForTargetToFaintAI(u32 battlerDef, u32 battlerAtk);
u32 GetBestDmgMoveFromBattler(u32 battlerAtk, u32 battlerDef);
u32 GetBestDmgFromBattler(u32 battler, u32 battlerTarget);
u32 GetBestDmgMoveFromBattler(u32 battlerAtk, u32 battlerDef, enum DamageCalcContext calcContext);
u32 GetBestDmgFromBattler(u32 battler, u32 battlerTarget, enum DamageCalcContext calcContext);
bool32 CanTargetMoveFaintAi(u32 move, u32 battlerDef, u32 battlerAtk, u32 nHits);
bool32 CanTargetFaintAiWithMod(u32 battlerDef, u32 battlerAtk, s32 hpMod, s32 dmgMod);
s32 AI_DecideKnownAbilityForTurn(u32 battlerId);
u32 AI_DecideHoldEffectForTurn(u32 battlerId);
enum ItemHoldEffect AI_DecideHoldEffectForTurn(u32 battlerId);
bool32 DoesBattlerIgnoreAbilityChecks(u32 battlerAtk, u32 atkAbility, u32 move);
u32 AI_GetWeather(void);
enum WeatherState IsWeatherActive(u32 flags);
bool32 CanAIFaintTarget(u32 battlerAtk, u32 battlerDef, u32 numHits);
bool32 CanIndexMoveFaintTarget(u32 battlerAtk, u32 battlerDef, u32 index, u32 numHits);
bool32 CanIndexMoveFaintTarget(u32 battlerAtk, u32 battlerDef, u32 index, enum DamageCalcContext calcContext);
bool32 CanIndexMoveGuaranteeFaintTarget(u32 battlerAtk, u32 battlerDef, u32 index);
bool32 HasDamagingMove(u32 battlerId);
bool32 HasDamagingMoveOfType(u32 battlerId, u32 type);
u32 GetBattlerSecondaryDamage(u32 battlerId);
@ -78,8 +97,8 @@ bool32 ShouldTryOHKO(u32 battlerAtk, u32 battlerDef, u32 atkAbility, u32 defAbil
bool32 ShouldUseRecoilMove(u32 battlerAtk, u32 battlerDef, u32 recoilDmg, u32 moveIndex);
u32 GetBattlerSideSpeedAverage(u32 battler);
bool32 ShouldAbsorb(u32 battlerAtk, u32 battlerDef, u32 move, s32 damage);
bool32 ShouldRecover(u32 battlerAtk, u32 battlerDef, u32 move, u32 healPercent);
bool32 ShouldSetScreen(u32 battlerAtk, u32 battlerDef, u32 moveEffect);
bool32 ShouldRecover(u32 battlerAtk, u32 battlerDef, u32 move, u32 healPercent, enum DamageCalcContext calcContext);
bool32 ShouldSetScreen(u32 battlerAtk, u32 battlerDef, enum BattleMoveEffects moveEffect);
enum AIPivot ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 moveIndex);
bool32 IsRecycleEncouragedItem(u32 item);
bool32 ShouldRestoreHpBerry(u32 battlerAtk, u32 item);
@ -87,13 +106,13 @@ bool32 IsStatBoostingBerry(u32 item);
bool32 CanKnockOffItem(u32 battler, u32 item);
bool32 IsAbilityOfRating(u32 ability, s8 rating);
bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability);
bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u32 move);
bool32 AI_MoveMakesContact(u32 ability, enum ItemHoldEffect holdEffect, u32 move);
bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, u32 chosenMove);
u32 AI_GetBattlerAbility(u32 battler);
// stat stage checks
bool32 AnyStatIsRaised(u32 battlerId);
bool32 ShouldLowerStat(u32 battlerAtk, u32 battlerDef, u32 battlerAbility, u32 stat);
bool32 ShouldLowerStat(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 stat);
bool32 BattlerStatCanRise(u32 battler, u32 battlerAbility, u32 stat);
bool32 AreBattlersStatsMaxed(u32 battler);
u32 CountPositiveStatStages(u32 battlerId);
@ -107,43 +126,44 @@ bool32 ShouldLowerAccuracy(u32 battlerAtk, u32 battlerDef, u32 defAbility);
bool32 ShouldLowerEvasion(u32 battlerAtk, u32 battlerDef, u32 defAbility);
// move checks
bool32 IsAffectedByPowder(u32 battler, u32 ability, u32 holdEffect);
bool32 IsAffectedByPowder(u32 battler, u32 ability, enum ItemHoldEffect holdEffect);
bool32 MovesWithCategoryUnusable(u32 attacker, u32 target, u32 category);
s32 AI_WhichMoveBetter(u32 move1, u32 move2, u32 battlerAtk, u32 battlerDef, s32 noOfHitsToKo);
struct SimulatedDamage AI_CalcDamageSaveBattlers(u32 move, u32 battlerAtk, u32 battlerDef, uq4_12_t *typeEffectiveness, bool32 considerZPower, enum DamageRollType rollType);
struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, uq4_12_t *typeEffectiveness, bool32 considerZPower, u32 weather, enum DamageRollType rollType);
struct SimulatedDamage AI_CalcDamageSaveBattlers(u32 move, u32 battlerAtk, u32 battlerDef, uq4_12_t *typeEffectiveness, bool32 considerZPower);
struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, uq4_12_t *typeEffectiveness, bool32 considerZPower, u32 weather);
bool32 AI_IsDamagedByRecoil(u32 battler);
u32 GetNoOfHitsToKO(u32 dmg, s32 hp);
u32 GetNoOfHitsToKOBattlerDmg(u32 dmg, u32 battlerDef);
u32 GetNoOfHitsToKOBattler(u32 battlerAtk, u32 battlerDef, u32 moveIndex);
u32 GetCurrDamageHpPercent(u32 battlerAtk, u32 battlerDef);
u32 GetNoOfHitsToKOBattler(u32 battlerAtk, u32 battlerDef, u32 moveIndex, enum DamageCalcContext calcContext);
u32 GetCurrDamageHpPercent(u32 battlerAtk, u32 battlerDef, enum DamageCalcContext calcContext);
uq4_12_t AI_GetMoveEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef);
u16 *GetMovesArray(u32 battler);
bool32 IsConfusionMoveEffect(u32 moveEffect);
bool32 IsConfusionMoveEffect(enum BattleMoveEffects moveEffect);
bool32 HasMove(u32 battlerId, u32 move);
bool32 HasOnlyMovesWithCategory(u32 battlerId, u32 category, bool32 onlyOffensive);
bool32 HasMoveWithCategory(u32 battler, u32 category);
bool32 HasMoveWithType(u32 battler, u32 type);
bool32 HasMoveEffect(u32 battlerId, u32 moveEffect);
bool32 IsPowerBasedOnStatus(u32 battlerId, u32 effect, u32 argument);
bool32 HasMoveWithEffect(u32 battlerId, enum BattleMoveEffects moveEffect);
bool32 HasNonVolatileMoveEffect(u32 battlerId, u32 effect);
bool32 IsPowerBasedOnStatus(u32 battlerId, enum BattleMoveEffects effect, u32 argument);
bool32 HasMoveWithAdditionalEffect(u32 battlerId, u32 moveEffect);
bool32 HasMoveWithCriticalHitChance(u32 battlerId);
bool32 HasMoveWithMoveEffectExcept(u32 battlerId, u32 moveEffect, u32 exception);
bool32 HasMoveWithMoveEffectExcept(u32 battlerId, u32 moveEffect, enum BattleMoveEffects exception);
bool32 HasMoveThatLowersOwnStats(u32 battlerId);
bool32 HasMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef, u32 accCheck, bool32 ignoreStatus, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect);
bool32 HasAnyKnownMove(u32 battlerId);
bool32 IsAromaVeilProtectedEffect(u32 moveEffect);
bool32 IsNonVolatileStatusMoveEffect(u32 moveEffect);
bool32 IsAromaVeilProtectedEffect(enum BattleMoveEffects moveEffect);
bool32 IsNonVolatileStatusMove(u32 moveEffect);
bool32 IsMoveRedirectionPrevented(u32 battlerAtk, u32 move, u32 atkAbility);
bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 IsHazardMove(u32 move);
bool32 IsTwoTurnNotSemiInvulnerableMove(u32 battlerAtk, u32 move);
void ProtectChecks(u32 battlerAtk, u32 battlerDef, u32 move, u32 predictedMove, s32 *score);
bool32 ShouldSetSandstorm(u32 battler, u32 ability, u32 holdEffect);
bool32 ShouldSetHail(u32 battler, u32 ability, u32 holdEffect);
bool32 ShouldSetSnow(u32 battler, u32 ability, u32 holdEffect);
bool32 ShouldSetRain(u32 battlerAtk, u32 ability, u32 holdEffect);
bool32 ShouldSetSun(u32 battlerAtk, u32 atkAbility, u32 holdEffect);
bool32 ShouldSetSandstorm(u32 battler, u32 ability, enum ItemHoldEffect holdEffect);
bool32 ShouldSetHail(u32 battler, u32 ability, enum ItemHoldEffect holdEffect);
bool32 ShouldSetSnow(u32 battler, u32 ability, enum ItemHoldEffect holdEffect);
bool32 ShouldSetRain(u32 battlerAtk, u32 ability, enum ItemHoldEffect holdEffect);
bool32 ShouldSetSun(u32 battlerAtk, u32 atkAbility, enum ItemHoldEffect holdEffect);
bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef);
bool32 IsHealingMove(u32 move);
bool32 HasHealingEffect(u32 battler);
@ -151,31 +171,29 @@ bool32 IsTrappingMove(u32 move);
bool32 HasTrappingMoveEffect(u32 battler);
bool32 ShouldFakeOut(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 HasThawingMove(u32 battler);
bool32 IsStatRaisingEffect(u32 effect);
bool32 IsStatLoweringEffect(u32 effect);
bool32 IsSelfStatLoweringEffect(u32 effect);
bool32 IsSwitchOutEffect(u32 effect);
bool32 IsChaseEffect(u32 effect);
bool32 IsAttackBoostMoveEffect(u32 effect);
bool32 IsUngroundingEffect(u32 effect);
bool32 IsStatRaisingEffect(enum BattleMoveEffects effect);
bool32 IsStatLoweringEffect(enum BattleMoveEffects effect);
bool32 IsSelfStatLoweringEffect(enum BattleMoveEffects effect);
bool32 IsSwitchOutEffect(enum BattleMoveEffects effect);
bool32 IsChaseEffect(enum BattleMoveEffects effect);
bool32 IsAttackBoostMoveEffect(enum BattleMoveEffects effect);
bool32 IsUngroundingEffect(enum BattleMoveEffects effect);
bool32 IsSemiInvulnerable(u32 battlerDef, u32 move);
bool32 HasSubstituteIgnoringMove(u32 battler);
bool32 HasHighCritRatioMove(u32 battler);
bool32 HasMagicCoatAffectedMove(u32 battler);
bool32 HasSnatchAffectedMove(u32 battler);
bool32 HasMoveWithFlag(u32 battler, MoveFlag getFlag);
bool32 IsHazardClearingMove(u32 move);
bool32 IsSubstituteEffect(u32 effect);
bool32 IsSubstituteEffect(enum BattleMoveEffects effect);
// status checks
bool32 AI_CanGetFrostbite(u32 battler, u32 ability);
bool32 AI_CanBeConfused(u32 battlerAtk, u32 battlerDef, u32 move, u32 ability);
bool32 IsBattlerIncapacitated(u32 battler, u32 ability);
bool32 AI_CanPutToSleep(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
bool32 ShouldPoisonSelf(u32 battler, u32 ability);
bool32 ShouldPoison(u32 battlerAtk, u32 battlerDef);
bool32 AI_CanPoison(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
bool32 AI_CanParalyze(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove);
bool32 AI_CanConfuse(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
bool32 ShouldBurnSelf(u32 battler, u32 ability);
bool32 ShouldBurn(u32 battlerAtk, u32 battlerDef, u32 abilityDef);
bool32 ShouldFreezeOrFrostbite(u32 battlerAtk, u32 battlerDef, u32 abilityDef);
bool32 ShouldParalyze(u32 battlerAtk, u32 battlerDef, u32 abilityDef);
bool32 AI_CanBurn(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
bool32 AI_CanGiveFrostbite(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove);
bool32 AI_CanBeInfatuated(u32 battlerAtk, u32 battlerDef, u32 defAbility);
@ -185,6 +203,10 @@ bool32 ShouldTrap(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 IsWakeupTurn(u32 battler);
bool32 AI_IsBattlerAsleepOrComatose(u32 battlerId);
// ability logic
bool32 IsMoxieTypeAbility(u32 ability);
bool32 ShouldTriggerAbility(u32 battler, u32 ability);
// partner logic
#define IS_TARGETING_PARTNER(battlerAtk, battlerDef)((battlerAtk) == (battlerDef ^ BIT_FLANK))
u32 GetAllyChosenMove(u32 battlerId);
@ -194,12 +216,14 @@ bool32 PartnerHasSameMoveEffectWithoutTarget(u32 battlerAtkPartner, u32 move, u3
bool32 PartnerMoveEffectIsStatusSameTarget(u32 battlerAtkPartner, u32 battlerDef, u32 partnerMove);
bool32 IsMoveEffectWeather(u32 move);
bool32 PartnerMoveEffectIsTerrain(u32 battlerAtkPartner, u32 partnerMove);
bool32 PartnerMoveEffectIs(u32 battlerAtkPartner, u32 partnerMove, u32 effectCheck);
bool32 PartnerMoveEffectIs(u32 battlerAtkPartner, u32 partnerMove, enum BattleMoveEffects effectCheck);
bool32 PartnerMoveIs(u32 battlerAtkPartner, u32 partnerMove, u32 moveCheck);
bool32 PartnerMoveIsSameAsAttacker(u32 battlerAtkPartner, u32 battlerDef, u32 move, u32 partnerMove);
bool32 PartnerMoveIsSameNoTarget(u32 battlerAtkPartner, u32 move, u32 partnerMove);
bool32 PartnerMoveActivatesSleepClause(u32 move);
bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u32 move);
u32 GetFriendlyFireKOThreshold(u32 battler);
bool32 IsAllyProtectingFromMove(u32 battlerAtk, u32 attackerMove, u32 allyMove);
// party logic
struct BattlePokemon *AllocSaveBattleMons(void);
@ -210,8 +234,8 @@ bool32 PartyHasMoveCategory(u32 battlerId, u32 category);
bool32 SideHasMoveCategory(u32 battlerId, u32 category);
// score increases
u32 IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, u32 statId);
u32 IncreaseStatUpScoreContrary(u32 battlerAtk, u32 battlerDef, u32 statId);
u32 IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, enum StatChange statId);
u32 IncreaseStatUpScoreContrary(u32 battlerAtk, u32 battlerDef, enum StatChange statId);
void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
@ -219,7 +243,7 @@ void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
s32 AI_CalcPartyMonDamage(u32 move, u32 battlerAtk, u32 battlerDef, struct BattlePokemon switchinCandidate, bool32 isPartyMonAttacker, enum DamageRollType rollType);
s32 AI_CalcPartyMonDamage(u32 move, u32 battlerAtk, u32 battlerDef, struct BattlePokemon switchinCandidate, enum DamageCalcContext calcContext);
u32 AI_WhoStrikesFirstPartyMon(u32 battlerAtk, u32 battlerDef, struct BattlePokemon switchinCandidate, u32 moveConsidered);
s32 AI_TryToClearStats(u32 battlerAtk, u32 battlerDef, bool32 isDoubleBattle);
bool32 AI_ShouldCopyStatChanges(u32 battlerAtk, u32 battlerDef);
@ -229,6 +253,9 @@ bool32 AI_ShouldSpicyExtract(u32 battlerAtk, u32 battlerAtkPartner, u32 move, st
u32 IncreaseSubstituteMoveScore(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 IsBattlerItemEnabled(u32 battler);
bool32 IsBattlerPredictedToSwitch(u32 battler);
u32 GetIncomingMove(u32 battler, u32 opposingBattler, struct AiLogicData *aiData);
bool32 HasLowAccuracyMove(u32 battlerAtk, u32 battlerDef);
bool32 HasBattlerSideAbility(u32 battlerDef, u32 ability, struct AiLogicData *aiData);
u32 GetThinkingBattler(u32 battler);
#endif //GUARD_BATTLE_AI_UTIL_H

View File

@ -38,7 +38,7 @@ struct BattleAnimBgData
struct BattleAnimBackground
{
const u32 *image;
const u32 *palette;
const u16 *palette;
const u32 *tilemap;
};
@ -239,7 +239,7 @@ u8 LaunchBallFadeMonTask(bool8 unfadeLater, u8 spritePalNum, u32 selectedPalette
bool32 IsCriticalCapture(void);
// battle_anim_utility_funcs.c
void InitStatsChangeAnimation(u8 taskId);
void StartMonScrollingBgMask(u8 taskId, int UNUSED unused, u16 scrollSpeed, u8 battler, bool8 includePartner, u8 numFadeSteps, u8 fadeStepDelay, u8 duration, const u32 *gfx, const u32 *tilemap, const u32 *palette);
void StartMonScrollingBgMask(u8 taskId, int UNUSED unused, u16 scrollSpeed, u8 battler, bool8 includePartner, u8 numFadeSteps, u8 fadeStepDelay, u8 duration, const u32 *gfx, const u32 *tilemap, const u16 *palette);
// battle_anim_effects_1.c
void AnimFalseSwipeSlice_Step3(struct Sprite *);
@ -433,7 +433,7 @@ extern const struct OamData gOamData_AffineOff_ObjBlend_16x32;
extern const struct OamData gOamData_AffineDouble_ObjBlend_32x8;
extern const struct CompressedSpriteSheet gBattleAnimPicTable[];
extern const struct CompressedSpritePalette gBattleAnimPaletteTable[];
extern const struct SpritePalette gBattleAnimPaletteTable[];
extern const struct SpriteTemplate gWaterHitSplatSpriteTemplate;
@ -554,6 +554,8 @@ void AnimDracoMeteorRock(struct Sprite *sprite);
void CoreEnforcerLoadBeamTarget(struct Sprite *sprite);
void SpriteCB_RandomCentredHits(struct Sprite *sprite);
void InitSpritePosToAnimTargetsCentre(struct Sprite *sprite, bool32 respectMonPicOffsets);
extern const union AffineAnimCmd *const gSpriteAffineAnimTable_PrimalSymbol[];
extern const union AffineAnimCmd *const gSpriteAffineAnimTable_MegaSymbol[];
// battle_anim_bug.c
void AnimTranslateStinger(struct Sprite *sprite);

View File

@ -1003,6 +1003,7 @@ extern const u8 gBattleAnimGeneral_Fog[];
extern const u8 gBattleAnimGeneral_TeraCharge[];
extern const u8 gBattleAnimGeneral_TeraActivate[];
extern const u8 gBattleAnimGeneral_SimpleHeal[];
extern const u8 gBattleAnimGeneral_PowerConstruct[];
// special animations
extern const u8 gBattleAnimSpecial_LevelUp[];

View File

@ -8,7 +8,7 @@ u8 BattleArena_ShowJudgmentWindow(u8 *state);
void BattleArena_InitPoints(void);
void BattleArena_AddMindPoints(u8 battler);
void BattleArena_AddSkillPoints(u8 battler);
void BattleArena_DeductSkillPoints(u8 battler, u16 stringId);
void BattleArena_DeductSkillPoints(u8 battler, enum StringID stringId);
void DrawArenaRefereeTextBox(void);
void EraseArenaRefereeTextBox(void);

View File

@ -268,8 +268,8 @@ void BtlController_EmitTrainerSlideBack(u32 battler, u32 bufferId);
void BtlController_EmitFaintAnimation(u32 battler, u32 bufferId);
void BtlController_EmitBallThrowAnim(u32 battler, u32 bufferId, u8 caseId);
void BtlController_EmitMoveAnimation(u32 battler, u32 bufferId, u16 move, u8 turnOfMove, u16 movePower, s32 dmg, u8 friendship, struct DisableStruct *disableStructPtr, u8 multihit);
void BtlController_EmitPrintString(u32 battler, u32 bufferId, u16 stringId);
void BtlController_EmitPrintSelectionString(u32 battler, u32 bufferId, u16 stringId);
void BtlController_EmitPrintString(u32 battler, u32 bufferId, enum StringID stringId);
void BtlController_EmitPrintSelectionString(u32 battler, u32 bufferId, enum StringID stringId);
void BtlController_EmitChooseAction(u32 battler, u32 bufferId, u8 action, u16 itemId);
void BtlController_EmitYesNoBox(u32 battler, u32 bufferId);
void BtlController_EmitChooseMove(u32 battler, u32 bufferId, bool8 isDoubleBattle, bool8 NoPpNumber, struct ChooseMoveStruct *movePpData);
@ -329,10 +329,6 @@ void BtlController_HandleHealthBarUpdate(u32 battler, bool32 updateHpText);
void DoStatusIconUpdate(u32 battler);
void BtlController_HandleStatusIconUpdate(u32 battler);
void BtlController_HandleStatusAnimation(u32 battler);
void BtlController_HandleClearUnkVar(u32 battler);
void BtlController_HandleSetUnkVar(u32 battler);
void BtlController_HandleClearUnkFlag(u32 battler);
void BtlController_HandleToggleUnkFlag(u32 battler);
void BtlController_HandleHitAnimation(u32 battler);
void BtlController_HandlePlaySE(u32 battler);
void BtlController_HandlePlayFanfareOrBGM(u32 battler);
@ -341,7 +337,7 @@ void BtlController_HandleIntroSlide(u32 battler);
void BtlController_HandleSpriteInvisibility(u32 battler);
bool32 TwoPlayerIntroMons(u32 battlerId); // Double battle with both player pokemon active.
bool32 TwoOpponentIntroMons(u32 battlerId); // Double battle with both opponent pokemon active.
void BtlController_HandleIntroTrainerBallThrow(u32 battler, u16 tagTrainerPal, const u32 *trainerPal, s16 framesToWait, void (*controllerCallback)(u32 battler));
void BtlController_HandleIntroTrainerBallThrow(u32 battler, u16 tagTrainerPal, const u16 *trainerPal, s16 framesToWait, void (*controllerCallback)(u32 battler));
void BtlController_HandleDrawPartyStatusSummary(u32 battler, u32 side, bool32 considerDelay);
void BtlController_HandleHidePartyStatusSummary(u32 battler);
void BtlController_HandleBattleAnimation(u32 battler, bool32 ignoreSE, bool32 updateTvData);
@ -394,4 +390,13 @@ void SetControllerToLinkOpponent(u32 battler);
// link partner
void SetControllerToLinkPartner(u32 battler);
void TrySetBattlerShadowSpriteCallback(u32 battler);
bool32 TryShinyAnimAfterMonAnimUtil(u32 battler);
bool32 SwitchIn_ShowSubstituteUtil(u32 battler);
bool32 SwitchIn_WaitAndEndUtil(u32 battler);
bool32 SwitchIn_HandleSoundAndEndUtil(u32 battler);
bool32 SwitchIn_ShowHealthboxUtil(u32 battler);
bool32 SwitchIn_TryShinyAnimUtil(u32 battler);
#endif // GUARD_BATTLE_CONTROLLERS_H

View File

@ -20,8 +20,6 @@ void ChooseDamageNonTypesString(u8 type);
void BS_UpdateDynamax(void);
void BS_SetSteelsurge(void);
void BS_TrySetStatus1(void);
void BS_TrySetStatus2(void);
void BS_HealOneSixth(void);
void BS_TryRecycleBerry(void);
void BS_JumpIfDynamaxed(void);

View File

@ -0,0 +1,7 @@
#ifndef GUARD_BATTLE_END_TURN
#define GUARD_BATTLE_END_TURN
u32 DoEndTurnEffects(void);
#endif // GUARD_BATTLE_END_TURN

View File

@ -6,7 +6,7 @@ bool8 InBattleFactory(void);
u8 GetFactoryMonFixedIV(u8 challengeNum, bool8 isLastBattle);
void FillFactoryBrainParty(void);
u8 GetNumPastRentalsRank(u8 battleMode, u8 lvlMode);
u32 GetAiScriptsInBattleFactory(void);
u64 GetAiScriptsInBattleFactory(void);
void SetMonMoveAvoidReturn(struct Pokemon *mon, u16 moveArg, u8 moveSlot);
#endif // GUARD_BATTLE_FACTORY_H

View File

@ -39,7 +39,6 @@ void HideGimmickTriggerSprite(void);
void DestroyGimmickTriggerSprite(void);
void LoadIndicatorSpritesGfx(void);
u32 GetIndicatorTileTag(u32 battler);
u32 GetIndicatorPalTag(u32 battler);
void UpdateIndicatorVisibilityAndType(u32 healthboxId, bool32 invisible);
void UpdateIndicatorOamPriority(u32 healthboxId, u32 oamPriority);

View File

@ -3,6 +3,14 @@
#include "battle_controllers.h"
// used for sBattlerCoords and sBattlerHealthboxCoords
enum BattleCoordTypes
{
BATTLE_COORDS_SINGLES,
BATTLE_COORDS_DOUBLES,
BATTLE_COORDS_COUNT,
};
enum
{
HP_CURRENT,
@ -100,7 +108,7 @@ enum
HEALTHBOX_SAFARI_BALLS_TEXT
};
u32 WhichBattleCoords(u32 battlerId);
enum BattleCoordTypes GetBattlerCoordsIndex(u32 battler);
u8 CreateBattlerHealthboxSprites(u8 battler);
u8 CreateSafariPlayerHealthboxSprites(void);
void SetBattleBarStruct(u8 battler, u8 healthboxSpriteId, s32 maxVal, s32 oldVal, s32 receivedValue);

View File

@ -3,6 +3,7 @@
#include "pokemon.h"
#include "data.h"
#include "constants/hold_effects.h"
// For displaying a multi battle partner's Pokémon in the party menu
struct MultiPartnerMenuPokemon
@ -23,7 +24,32 @@ struct MultiPartnerMenuPokemon
#define BOUNCE_MON 0x0
#define BOUNCE_HEALTHBOX 0x1
enum {
enum BattleIntroStates
{
BATTLE_INTRO_STATE_GET_MON_DATA,
BATTLE_INTRO_STATE_LOOP_BATTLER_DATA,
BATTLE_INTRO_STATE_PREPARE_BG_SLIDE,
BATTLE_INTRO_STATE_WAIT_FOR_BG_SLIDE,
BATTLE_INTRO_STATE_DRAW_SPRITES,
BATTLE_INTRO_STATE_DRAW_PARTY_SUMMARY,
BATTLE_INTRO_STATE_WAIT_FOR_PARTY_SUMMARY,
BATTLE_INTRO_STATE_INTRO_TEXT,
BATTLE_INTRO_STATE_WAIT_FOR_INTRO_TEXT,
BATTLE_INTRO_STATE_TRAINER_SEND_OUT_TEXT,
BATTLE_INTRO_STATE_WAIT_FOR_TRAINER_SEND_OUT_TEXT,
BATTLE_INTRO_STATE_TRAINER_1_SEND_OUT_ANIM,
BATTLE_INTRO_STATE_TRAINER_2_SEND_OUT_ANIM,
BATTLE_INTRO_STATE_WAIT_FOR_TRAINER_2_SEND_OUT_ANIM,
BATTLE_INTRO_STATE_WAIT_FOR_WILD_BATTLE_TEXT,
BATTLE_INTRO_STATE_PRINT_PLAYER_SEND_OUT_TEXT,
BATTLE_INTRO_STATE_WAIT_FOR_PLAYER_SEND_OUT_TEXT,
BATTLE_INTRO_STATE_PRINT_PLAYER_1_SEND_OUT_TEXT,
BATTLE_INTRO_STATE_PRINT_PLAYER_2_SEND_OUT_TEXT,
BATTLE_INTRO_STATE_SET_DEX_AND_BATTLE_VARS
};
enum FirstTurnEventsStates
{
FIRST_TURN_EVENTS_START,
FIRST_TURN_EVENTS_OVERWORLD_WEATHER,
FIRST_TURN_EVENTS_TERRAIN,
@ -69,12 +95,12 @@ u8 IsRunningFromBattleImpossible(u32 battler);
void SwitchTwoBattlersInParty(u32 battler, u32 battler2);
void SwitchPartyOrder(u32 battler);
void SwapTurnOrder(u8 id1, u8 id2);
u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect);
u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, enum ItemHoldEffect holdEffect);
u32 GetBattlerTotalSpeedStat(u32 battler);
s8 GetChosenMovePriority(u32 battlerId);
s8 GetBattleMovePriority(u32 battlerId, u16 move);
s32 GetChosenMovePriority(u32 battler, u32 ability);
s32 GetBattleMovePriority(u32 battler, u32 ability, u32 move);
s32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMoves, u32 ability1, u32 ability2,
u32 holdEffectBattler1, u32 holdEffectBattler2, u32 speedBattler1, u32 speedBattler2, s32 priority1, s32 priority2);
enum ItemHoldEffect holdEffectBattler1, enum ItemHoldEffect holdEffectBattler2, u32 speedBattler1, u32 speedBattler2, s32 priority1, s32 priority2);
s32 GetWhichBattlerFasterOrTies(u32 battler1, u32 battler2, bool32 ignoreChosenMoves);
s32 GetWhichBattlerFaster(u32 battler1, u32 battler2, bool32 ignoreChosenMoves);
void RunBattleScriptCommands_PopCallbacksStack(void);
@ -87,6 +113,8 @@ u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer
void ModifyPersonalityForNature(u32 *personality, u32 newNature);
u32 GeneratePersonalityForGender(u32 gender, u32 species);
void CustomTrainerPartyAssignMoves(struct Pokemon *mon, const struct TrainerMon *partyEntry);
bool32 CanPlayerForfeitNormalTrainerBattle(void);
bool32 DidPlayerForfeitNormalTrainerBattle(void);
extern struct MultiPartnerMenuPokemon gMultiPartnerParty[MULTI_PARTY_SIZE];

View File

@ -2,6 +2,7 @@
#define GUARD_BATTLE_MESSAGE_H
#include "constants/battle.h"
#include "constants/battle_string_ids.h"
// This buffer can hold many different things. Some of the things it can hold
// that have explicit sizes are listed below to ensure it can contain them.
@ -247,7 +248,7 @@ struct BattleMsgData
u8 textBuffs[3][TEXT_BUFF_ARRAY_COUNT];
};
void BufferStringBattle(u16 stringID, u32 battler);
void BufferStringBattle(enum StringID stringID, u32 battler);
u32 BattleStringExpandPlaceholdersToDisplayedString(const u8 *src);
u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize);
void BattlePutTextOnWindow(const u8 *text, u8 windowId);

View File

@ -22,10 +22,12 @@ struct PickupItem
u8 percentage[10];
};
s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility, u32 abilityAtk, u32 abilityDef, u32 holdEffectAtk);
s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility, u32 abilityAtk, u32 abilityDef, enum ItemHoldEffect holdEffectAtk);
s32 CalcCritChanceStageGen1(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility, u32 abilityAtk, u32 abilityDef, enum ItemHoldEffect holdEffectAtk);
s32 GetCritHitOdds(s32 critChanceIndex);
u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect);
u8 GetBattlerTurnOrderNum(u8 battler);
bool32 NoAliveMonsForBattlerSide(u32 battler);
bool32 NoAliveMonsForPlayer(void);
bool32 NoAliveMonsForEitherParty(void);
void SetMoveEffect(bool32 primary, bool32 certain);
@ -37,8 +39,6 @@ void HandleBattleWindow(u8 xStart, u8 yStart, u8 xEnd, u8 yEnd, u8 flags);
bool8 UproarWakeUpCheck(u8 battler);
bool32 DoesSubstituteBlockMove(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 DoesDisguiseBlockMove(u32 battler, u32 move);
bool32 CanPoisonType(u8 battlerAttacker, u8 battlerTarget);
bool32 CanParalyzeType(u8 battlerAttacker, u8 battlerTarget);
bool32 CanUseLastResort(u8 battlerId);
u32 IsFlowerVeilProtected(u32 battler);
u32 IsLeafGuardProtected(u32 battler, u32 ability);
@ -57,6 +57,8 @@ u8 GetFirstFaintedPartyIndex(u8 battlerId);
bool32 IsMoveAffectedByParentalBond(u32 move, u32 battler);
void SaveBattlerTarget(u32 battler);
void SaveBattlerAttacker(u32 battler);
bool32 CanBurnHitThaw(u16 move);
void SetNonVolatileStatusCondition(u32 target, enum MoveEffects effect);
extern void (*const gBattleScriptingCommandsTable[])(void);
extern const struct StatFractions gAccuracyStageRatios[];

View File

@ -101,6 +101,8 @@ extern const u8 BattleScript_SelectingTormentedMoveInPalace[];
extern const u8 BattleScript_SelectingNotAllowedMoveTaunt[];
extern const u8 BattleScript_MoveUsedIsTaunted[];
extern const u8 BattleScript_SelectingNotAllowedMoveTauntInPalace[];
extern const u8 BattleScript_WishButHealBlocked[];
extern const u8 BattleScript_WishButFullHp[];
extern const u8 BattleScript_WishComesTrue[];
extern const u8 BattleScript_IngrainTurnHeal[];
extern const u8 BattleScript_AtkDefDown[];
@ -185,9 +187,6 @@ extern const u8 BattleScript_FlashFireBoost[];
extern const u8 BattleScript_AbilityNoStatLoss[];
extern const u8 BattleScript_ItemNoStatLoss[];
extern const u8 BattleScript_ItemNoStatLossSpicyExtract[];
extern const u8 BattleScript_BRNPrevention[];
extern const u8 BattleScript_PRLZPrevention[];
extern const u8 BattleScript_PSNPrevention[];
extern const u8 BattleScript_ObliviousPreventsAttraction[];
extern const u8 BattleScript_FlinchPrevention[];
extern const u8 BattleScript_OwnTempoPrevents[];
@ -271,7 +270,6 @@ extern const u8 BattleScript_WonderRoomEnds[];
extern const u8 BattleScript_MagicRoomEnds[];
extern const u8 BattleScript_TerrainEnds[];
extern const u8 BattleScript_TerrainEnds_Ret[];
extern const u8 BattleScript_GrassyTerrainEnds[];
extern const u8 BattleScript_MudSportEnds[];
extern const u8 BattleScript_WaterSportEnds[];
extern const u8 BattleScript_SturdiedMsg[];
@ -370,6 +368,8 @@ extern const u8 BattleScript_FlameOrb[];
extern const u8 BattleScript_MoveEffectIncinerate[];
extern const u8 BattleScript_MoveEffectBugBite[];
extern const u8 BattleScript_IllusionOff[];
extern const u8 BattleScript_IllusionOffEnd3[];
extern const u8 BattleScript_IllusionOffAndTerastallization[];
extern const u8 BattleScript_DancerActivates[];
extern const u8 BattleScript_AftermathDmg[];
extern const u8 BattleScript_AttackerFormChange[];
@ -388,6 +388,8 @@ extern const u8 BattleScript_FriskMsgWithPopup[];
extern const u8 BattleScript_MoodyActivates[];
extern const u8 BattleScript_EmergencyExit[];
extern const u8 BattleScript_EmergencyExitWild[];
extern const u8 BattleScript_EmergencyExitEnd2[];
extern const u8 BattleScript_EmergencyExitWildEnd2[];
extern const u8 BattleScript_CheekPouchActivates[];
extern const u8 BattleScript_TotemVar[];
extern const u8 BattleScript_TotemFlaredToLife[];
@ -428,6 +430,7 @@ extern const u8 BattleScript_GulpMissileGorging[];
extern const u8 BattleScript_GulpMissileGulping[];
extern const u8 BattleScript_GulpMissileFormChange[];
extern const u8 BattleScript_BattleBondActivatesOnMoveEndAttacker[];
extern const u8 BattleScript_EffectBattleBondStatIncrease[];
extern const u8 BattleScript_DesolateLandActivates[];
extern const u8 BattleScript_PrimordialSeaActivates[];
extern const u8 BattleScript_PrimalWeatherBlocksMove[];
@ -516,6 +519,19 @@ extern const u8 BattleScript_BoosterEnergyRet[];
extern const u8 BattleScript_TeraShellDistortingTypeMatchups[];
extern const u8 BattleScript_TeraFormChange[];
extern const u8 BattleScript_SleepClausePreventsEnd[];
extern const u8 BattleScript_PowerConstruct[];
extern const u8 BattleScript_AbilityProtectsDoesntAffect[];
extern const u8 BattleScript_ImmunityProtected[];
extern const u8 BattleScript_SafeguardProtected[];
extern const u8 BattleScript_FlowerVeilProtects[];
extern const u8 BattleScript_SleepClauseBlocked[];
extern const u8 BattleScript_AlreadyAsleep[];
extern const u8 BattleScript_CantMakeAsleep[];
extern const u8 BattleScript_AlreadyPoisoned[];
extern const u8 BattleScript_AlreadyParalyzed[];
extern const u8 BattleScript_AlreadyBurned[];
extern const u8 BattleScript_PrintAbilityMadeIneffective[];
// zmoves
extern const u8 BattleScript_ZMoveActivateDamaging[];
@ -563,7 +579,6 @@ extern const u8 BattleScript_DynamaxEnds_Ret[];
extern const u8 BattleScript_MoveBlockedByDynamax[];
// Battle move scripts
extern const u8 BattleScript_EffectSleep[];
extern const u8 BattleScript_EffectAbsorb[];
extern const u8 BattleScript_EffectAbsorbLiquidOoze[];
extern const u8 BattleScript_EffectExplosion[];
@ -590,12 +605,9 @@ extern const u8 BattleScript_EffectRoar[];
extern const u8 BattleScript_EffectHit[];
extern const u8 BattleScript_EffectConversion[];
extern const u8 BattleScript_EffectRestoreHp[];
extern const u8 BattleScript_EffectToxic[];
extern const u8 BattleScript_EffectLightScreen[];
extern const u8 BattleScript_EffectRest[];
extern const u8 BattleScript_EffectOHKO[];
extern const u8 BattleScript_EffectSuperFang[];
extern const u8 BattleScript_EffectFixedDamageArg[];
extern const u8 BattleScript_EffectHealBlock[];
extern const u8 BattleScript_RecoilIfMiss[];
extern const u8 BattleScript_EffectMist[];
@ -617,8 +629,6 @@ extern const u8 BattleScript_EffectSpecialDefenseDown2[];
extern const u8 BattleScript_EffectAccuracyDown2[];
extern const u8 BattleScript_EffectEvasionDown2[];
extern const u8 BattleScript_EffectReflect[];
extern const u8 BattleScript_EffectPoison[];
extern const u8 BattleScript_EffectParalyze[];
extern const u8 BattleScript_EffectTwoTurnsAttack[];
extern const u8 BattleScript_EffectSubstitute[];
extern const u8 BattleScript_EffectRage[];
@ -630,8 +640,6 @@ extern const u8 BattleScript_EffectHoldHands[];
extern const u8 BattleScript_EffectCelebrate[];
extern const u8 BattleScript_EffectHappyHour[];
extern const u8 BattleScript_EffectDisable[];
extern const u8 BattleScript_EffectLevelDamage[];
extern const u8 BattleScript_EffectPsywave[];
extern const u8 BattleScript_EffectCounter[];
extern const u8 BattleScript_EffectEncore[];
extern const u8 BattleScript_EffectPainSplit[];
@ -690,7 +698,7 @@ extern const u8 BattleScript_EffectWorrySeed[];
extern const u8 BattleScript_EffectHail[];
extern const u8 BattleScript_EffectTorment[];
extern const u8 BattleScript_EffectFlatter[];
extern const u8 BattleScript_EffectWillOWisp[];
extern const u8 BattleScript_EffectNonVolatileStatus[];
extern const u8 BattleScript_EffectMemento[];
extern const u8 BattleScript_EffectFocusPunch[];
extern const u8 BattleScript_EffectFollowMe[];
@ -825,7 +833,6 @@ extern const u8 BattleScript_MoveEffectHaze[];
extern const u8 BattleScript_MoveEffectIonDeluge[];
extern const u8 BattleScript_EffectHyperspaceFury[];
extern const u8 BattleScript_EffectAuraWheel[];
extern const u8 BattleScript_EffectDynamicCategory[];
extern const u8 BattleScript_EffectNoRetreat[];
extern const u8 BattleScript_EffectTarShot[];
extern const u8 BattleScript_EffectPoltergeist[];
@ -859,5 +866,8 @@ extern const u8 BattleScript_EffectSpicyExtract[];
extern const u8 BattleScript_DamageToQuarterTargetHP[];
extern const u8 BattleScript_EffectFickleBeam[];
extern const u8 BattleScript_FickleBeamDoubled[];
extern const u8 BattleScript_QuestionForfeitBattle[];
extern const u8 BattleScript_ForfeitBattleGaveMoney[];
extern const u8 BattleScript_AbilityPopUp[];
#endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -77,5 +77,6 @@ u16 FacilityClassToGraphicsId(u8 facilityClass);
bool32 ValidateBattleTowerRecord(u8 recordId); // unused
void TrySetLinkBattleTowerEnemyPartyLevel(void);
void CreateFacilityMon(const struct TrainerMon *fmon, u16 level, u8 fixedIV, u32 otID, u32 flags, struct Pokemon *dst);
void FillPartnerParty(u16 trainerId);
#endif //GUARD_BATTLE_TOWER_H

View File

@ -1,7 +1,7 @@
#ifndef GUARD_BATTLE_TV_H
#define GUARD_BATTLE_TV_H
void BattleTv_SetDataBasedOnString(u16 stringId);
void BattleTv_SetDataBasedOnString(enum StringID stringId);
void BattleTv_SetDataBasedOnMove(u16 move, u16 weatherFlags, struct DisableStruct *disableStructPtr);
void BattleTv_SetDataBasedOnAnimation(u8 animationId);
void TryPutLinkBattleTvShowOnAir(void);

View File

@ -2,6 +2,7 @@
#define GUARD_BATTLE_UTIL_H
#include "move.h"
#include "constants/battle_string_ids.h"
#define MOVE_LIMITATION_ZEROMOVE (1 << 0)
#define MOVE_LIMITATION_PP (1 << 1)
@ -22,9 +23,16 @@
#define MOVE_LIMITATION_PLACEHOLDER (1 << 15)
#define MOVE_LIMITATIONS_ALL 0xFFFF
enum NonVolatileStatus
{
STATUS_CHECK_TRIGGER,
STATUS_RUN_SCRIPT,
};
enum AbilityEffectOptions
{
ABILITY_CHECK_TRIGGER,
ABILITY_CHECK_TRIGGER_AI,
ABILITY_RUN_SCRIPT,
};
@ -39,10 +47,6 @@ enum MoveAbsorbed
enum {
ABILITYEFFECT_ON_SWITCHIN,
ABILITYEFFECT_ENDTURN,
ABILITYEFFECT_MOVES_BLOCK,
ABILITYEFFECT_WOULD_BLOCK, // Checks immunity without triggering a script
ABILITYEFFECT_ABSORBING,
ABILITYEFFECT_WOULD_ABSORB, // Checks immunity without triggering a script
ABILITYEFFECT_MOVE_END_ATTACKER,
ABILITYEFFECT_MOVE_END,
ABILITYEFFECT_IMMUNITY,
@ -70,6 +74,7 @@ enum ItemCaseId
ITEMEFFECT_ON_SWITCH_IN,
ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN,
ITEMEFFECT_NORMAL,
ITEMEFFECT_TRY_HEALING,
ITEMEFFECT_MOVE_END,
ITEMEFFECT_KINGSROCK,
ITEMEFFECT_TARGET,
@ -96,6 +101,10 @@ enum ItemEffect
#define DMG_ROLL_PERCENT_LO 85
#define DMG_ROLL_PERCENT_HI 100
// Crit chance exceptions
#define CRITICAL_HIT_BLOCKED -1
#define CRITICAL_HIT_ALWAYS -2
// for Natural Gift and Fling
struct TypePower
{
@ -169,7 +178,22 @@ enum SleepClauseBlock
BLOCKED_BY_SLEEP_CLAUSE,
};
enum SkyDropState
{
SKY_DROP_IGNORE,
SKY_DROP_ATTACKCANCELLER_CHECK,
SKY_DROP_GRAVITY_ON_AIRBORNE,
SKY_DROP_CANCEL_MULTI_TURN_MOVES,
SKY_DROP_STATUS_YAWN,
SKY_DROP_STATUS_FREEZE_SLEEP,
};
#define SKY_DROP_NO_TARGET 0xFF
#define SKY_DROP_RELEASED_TARGET 0xFE
void HandleAction_ThrowBall(void);
u32 GetCurrentBattleWeather(void);
bool32 EndOrContinueWeather(void);
bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move);
bool32 HandleMoveTargetRedirection(void);
void HandleAction_UseMove(void);
@ -190,9 +214,9 @@ u8 GetBattlerForBattleScript(u8 caseId);
bool32 IsBattlerMarkedForControllerExec(u32 battler);
void MarkBattlerForControllerExec(u32 battler);
void MarkBattlerReceivedLinkData(u32 battler);
const u8* CancelMultiTurnMoves(u32 battler);
const u8 *CancelMultiTurnMoves(u32 battler, enum SkyDropState skyDropState);
bool32 WasUnableToUseMove(u32 battler);
void PrepareStringBattle(u16 stringId, u32 battler);
void PrepareStringBattle(enum StringID stringId, u32 battler);
void ResetSentPokesToOpponentValue(void);
void OpponentSwitchInResetSentPokesToOpponentValue(u32 battler);
void UpdateSentPokesToOpponentValue(u32 battler);
@ -203,18 +227,16 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler);
u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check);
bool32 AreAllMovesUnusable(u32 battler);
u8 GetImprisonedMovesCount(u32 battler, u16 move);
u8 DoFieldEndTurnEffects(void);
s32 GetDrainedBigRootHp(u32 battler, s32 hp);
bool32 IsMagicGuardProtected(u32 battler, u32 ability);
u8 DoBattlerEndTurnEffects(void);
bool32 HandleWishPerishSongOnTurnEnd(void);
u32 DoEndTurnEffects(void);
bool32 HandleFaintedMonActions(void);
void TryClearRageAndFuryCutter(void);
u32 AtkCanceller_MoveSuccessOrder(void);
void SetAtkCancellerForCalledMove(void);
bool32 HasNoMonsToSwitch(u32 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2);
bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, bool32 viaAbility);
bool32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 move, u32 abilityDef, enum AbilityEffectOptions option);
bool32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 abilityDef, u32 move, enum AbilityEffectOptions option);
bool32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 move, u32 moveType, enum AbilityEffectOptions option);
u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg);
bool32 TryPrimalReversion(u32 battler);
@ -227,6 +249,7 @@ u32 IsAbilityOnField(u32 ability);
u32 IsAbilityOnFieldExcept(u32 battler, u32 ability);
u32 IsAbilityPreventingEscape(u32 battler);
bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move);
u32 GetProtectType(enum ProtectMethod method);
bool32 CanBattlerEscape(u32 battler); // no ability check
void BattleScriptExecute(const u8 *BS_ptr);
void BattleScriptPushCursorAndCallback(const u8 *BS_ptr);
@ -236,9 +259,9 @@ void HandleAction_RunBattleScript(void);
u32 SetRandomTarget(u32 battler);
u32 GetBattleMoveTarget(u16 move, u8 setTarget);
u8 GetAttackerObedienceForAction();
u32 GetBattlerHoldEffect(u32 battler, bool32 checkNegating);
u32 GetBattlerHoldEffectIgnoreAbility(u32 battler, bool32 checkNegating);
u32 GetBattlerHoldEffectInternal(u32 battler, bool32 checkNegating, bool32 checkAbility);
enum ItemHoldEffect GetBattlerHoldEffect(u32 battler, bool32 checkNegating);
enum ItemHoldEffect GetBattlerHoldEffectIgnoreAbility(u32 battler, bool32 checkNegating);
enum ItemHoldEffect GetBattlerHoldEffectInternal(u32 battler, bool32 checkNegating, bool32 checkAbility);
u32 GetBattlerHoldEffectParam(u32 battler);
bool32 IsMoveMakingContact(u32 move, u32 battlerAtk);
bool32 IsBattlerGrounded(u32 battler);
@ -248,7 +271,8 @@ u32 CalcRolloutBasePower(u32 battlerAtk, u32 basePower, u32 rolloutTimer);
u32 CalcFuryCutterBasePower(u32 basePower, u32 furyCutterCounter);
s32 CalculateMoveDamage(struct DamageCalculationData *damageCalcData, u32 fixedBasePower);
s32 CalculateMoveDamageVars(struct DamageCalculationData *damageCalcData, u32 fixedBasePower, uq4_12_t typeEffectivenessModifier,
u32 weather, u32 holdEffectAtk, u32 holdEffectDef, u32 abilityAtk, u32 abilityDef);
u32 weather, enum ItemHoldEffect holdEffectAtk, enum ItemHoldEffect holdEffectDef, u32 abilityAtk, u32 abilityDef);
s32 ApplyModifiersAfterDmgRoll(s32 dmg, struct DamageCalculationData *damageCalcData, uq4_12_t typeEffectivenessModifier, u32 abilityAtk, u32 abilityDef, enum ItemHoldEffect holdEffectAtk, enum ItemHoldEffect holdEffectDef);
uq4_12_t CalcTypeEffectivenessMultiplier(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, u32 defAbility, bool32 recordAbilities);
uq4_12_t CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef);
uq4_12_t GetTypeModifier(u32 atkType, u32 defType);
@ -263,16 +287,20 @@ void ActivateUltraBurst(u32 battler);
bool32 IsBattlerMegaEvolved(u32 battler);
bool32 IsBattlerPrimalReverted(u32 battler);
bool32 IsBattlerUltraBursted(u32 battler);
u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method);
bool32 TryBattleFormChange(u32 battler, u32 method);
u16 GetBattleFormChangeTargetSpecies(u32 battler, enum FormChanges method);
bool32 TryBattleFormChange(u32 battler, enum FormChanges method);
bool32 DoBattlersShareType(u32 battler1, u32 battler2);
bool32 CanBattlerGetOrLoseItem(u32 battler, u16 itemId);
u32 GetBattlerVisualSpecies(u32 battler);
bool32 TryClearIllusion(u32 battler, u32 caseID);
u32 GetIllusionMonSpecies(u32 battler);
struct Pokemon *GetIllusionMonPtr(u32 battler);
void ClearIllusionMon(u32 battler);
u32 GetIllusionMonPartyId(struct Pokemon *party, struct Pokemon *mon, struct Pokemon *partnerMon);
bool32 SetIllusionMon(struct Pokemon *mon, u32 battler);
bool32 ShouldGetStatBadgeBoost(u16 flagId, u32 battler);
u8 GetBattleMoveCategory(u32 moveId);
u32 GetBattleMoveCategory(u32 move);
void SetDynamicMoveCategory(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 CanFling(u32 battler);
bool32 IsTelekinesisBannedSpecies(u16 species);
bool32 IsHealBlockPreventingMove(u32 battler, u32 move);
@ -292,7 +320,7 @@ bool32 IsBattlerAffectedByHazards(u32 battler, bool32 toxicSpikes);
void SortBattlersBySpeed(u8 *battlers, bool32 slowToFast);
bool32 CompareStat(u32 battler, u8 statId, u8 cmpTo, u8 cmpKind);
bool32 TryRoomService(u32 battler);
void BufferStatChange(u32 battler, u8 statId, u8 stringId);
void BufferStatChange(u32 battler, u8 statId, enum StringID stringId);
bool32 BlocksPrankster(u16 move, u32 battlerPrankster, u32 battlerDef, bool32 checkTarget);
u16 GetUsedHeldItem(u32 battler);
bool32 PickupHasValidTarget(u32 battler);
@ -314,16 +342,18 @@ bool32 TargetFullyImmuneToCurrMove(u32 battlerAtk, u32 battlerDef);
bool32 MoodyCantRaiseStat(u32 stat);
bool32 MoodyCantLowerStat(u32 stat);
bool32 CanBeSlept(u32 battler, u32 ability, enum SleepClauseBlock isBlockedBySleepClause);
bool32 CanBePoisoned(u32 battlerAtk, u32 battlerDef, u32 defAbility);
bool32 CanBeBurned(u32 battler, u32 ability);
bool32 CanBeParalyzed(u32 battler, u32 ability);
bool32 CanBeFrozen(u32 battler);
bool32 CanGetFrostbite(u32 battler);
bool32 CanBeSlept(u32 battlerAtk, u32 battlerDef, u32 abilityDef, enum SleepClauseBlock isBlockedBySleepClause);
bool32 CanBePoisoned(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 abilityDef);
bool32 CanBeBurned(u32 battlerAtk, u32 battlerDef, u32 ability);
bool32 CanBeParalyzed(u32 battlerAtk, u32 battlerDef, u32 abilityDef);
bool32 CanBeFrozen(u32 battlerAtk, u32 battlerDef, u32 abilityDef);
bool32 CanGetFrostbite(u32 battlerAtk, u32 battlerDef, u32 abilityDef);
bool32 CanSetNonVolatileStatus(u32 battlerAtk, u32 battlerDef, u32 abilityAtk, u32 abilityDef, enum MoveEffects secondaryMoveEffect, enum NonVolatileStatus option);
bool32 CanBeConfused(u32 battler);
bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag);
u32 GetBattlerAffectionHearts(u32 battler);
void TryToRevertMimicryAndFlags(void);
bool32 BattleArenaTurnEnd(void);
u32 CountBattlerStatIncreases(u32 battler, bool32 countEvasionAcc);
bool32 ChangeTypeBasedOnTerrain(u32 battler);
void RemoveConfusionStatus(u32 battler);
@ -345,14 +375,14 @@ bool32 IsSleepClauseEnabled();
void ClearDamageCalcResults(void);
u32 DoesDestinyBondFail(u32 battler);
bool32 IsMoveEffectBlockedByTarget(u32 ability);
u32 NumAffectedSpreadMoveTargets(void);
bool32 IsPursuitTargetSet(void);
void ClearPursuitValuesIfSet(u32 battler);
void ClearPursuitValues(void);
bool32 HasWeatherEffect(void);
bool32 IsMovePowderBlocked(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 EmergencyExitCanBeTriggered(u32 battler);
u32 RestoreWhiteHerbStats(u32 battler);
bool32 IsFutureSightAttackerInParty(u32 battlerAtk, u32 battlerDef);
bool32 IsFutureSightAttackerInParty(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 HadMoreThanHalfHpNowDoesnt(u32 battler);
void UpdateStallMons(void);
bool32 TryRestoreHPBerries(u32 battler, enum ItemCaseId caseId);
#endif // GUARD_BATTLE_UTIL_H

View File

@ -5,5 +5,6 @@
void InitTimeBasedEvents(void);
void DoTimeBasedEvents(void);
void FormChangeTimeUpdate();
#endif // GUARD_CLOCK_H

View File

@ -22,6 +22,7 @@
#define SHOULD_SWITCH_CHOICE_LOCKED_PERCENTAGE 100 // Only if locked into status move
#define SHOULD_SWITCH_ATTACKING_STAT_MINUS_TWO_PERCENTAGE 50
#define SHOULD_SWITCH_ATTACKING_STAT_MINUS_THREE_PLUS_PERCENTAGE 100
#define SHOULD_SWITCH_ALL_SCORES_BAD_PERCENTAGE 100
// AI smart switching chances for bad statuses
#define SHOULD_SWITCH_PERISH_SONG_PERCENTAGE 100
@ -44,10 +45,33 @@
#define SHOULD_SWITCH_REGENERATOR_PERCENTAGE 50
#define SHOULD_SWITCH_REGENERATOR_STATS_RAISED_PERCENTAGE 20
// AI switchin considerations
#define ALL_MOVES_BAD_STATUS_MOVES_BAD FALSE // If the AI has no moves that affect the target, ShouldSwitchIfAllMovesBad can prompt a switch. Enabling this config will ignore status moves that can affect the target when making this decision.
#define AI_BAD_SCORE_THRESHOLD 90 // Move scores beneath this threshold are considered "bad" when deciding switching
#define AI_GOOD_SCORE_THRESHOLD 100 // Move scores above this threshold are considered "good" when deciding switching
// AI held item-based move scoring
#define LOW_ACCURACY_THRESHOLD 75 // Moves with accuracy equal OR below this value are considered low accuracy
// AI move scoring
#define STATUS_MOVE_FOCUS_PUNCH_CHANCE 50 // Chance the AI will use a status move if the player's best move is Focus Punch
// AI damage calc considerations
#define RISKY_AI_CRIT_STAGE_THRESHOLD 2 // Stat stages at which Risky will assume it gets a crit
#define RISKY_AI_CRIT_THRESHOLD_GEN_1 128 // "Stat stage" at which Risky will assume it gets a crit with gen 1 mechanics (this translates to an X / 255 % crit threshold)
// AI prediction chances
#define PREDICT_SWITCH_CHANCE 50
#define PREDICT_MOVE_CHANCE 100
// AI PP Stall detection chance per roll
#define PP_STALL_DISREGARD_MOVE_PERCENTAGE 50
// Score reduction if any roll for PP stall detection passes
#define PP_STALL_SCORE_REDUCTION 20
// AI's acceptable number of hits to KO the partner via friendly fire in a double battle.
#define FRIENDLY_FIRE_RISKY_THRESHOLD 2
#define FRIENDLY_FIRE_NORMAL_THRESHOLD 3
#define FRIENDLY_FIRE_CONSERVATIVE_THRESHOLD 4
#endif // GUARD_CONFIG_AI_H

View File

@ -9,7 +9,6 @@
#define B_MULTI_HIT_CHANCE GEN_LATEST // In Gen5+, multi-hit moves have different %. See SetRandomMultiHitCounter for values.
#define B_WHITEOUT_MONEY GEN_LATEST // In Gen4+, the amount of money lost by losing a battle is determined by the amount of badges earned. Previously, it would cut the current money by half. (While this change was also in FRLG, for the sake of simplicity, setting this to GEN_3 will result in RSE behavior.)
#define B_LIGHT_BALL_ATTACK_BOOST GEN_LATEST // In Gen4+, Light Ball doubles the power of physical moves in addition to special moves.
#define B_SANDSTORM_SPDEF_BOOST GEN_LATEST // In Gen4+, Sandstorm weather multiplies the Sp. Defense of Rock-type Pokémon by x1.5.
// Experience settings
#define B_EXP_CATCH GEN_LATEST // In Gen6+, Pokémon get experience from catching.
@ -17,6 +16,7 @@
#define B_SPLIT_EXP GEN_LATEST // In Gen6+, all participating mon get full experience.
#define B_SCALED_EXP GEN_LATEST // In Gen5 and Gen7+, experience is weighted by level difference.
#define B_UNEVOLVED_EXP_MULTIPLIER GEN_LATEST // In Gen6+, if the Pokémon is at or past the level where it would be able to evolve, but it has not, it gets a ~1.2 multiplier to EXP gain. Only applies to Pokémon with EVO_LEVEL method.
#define B_LEVEL_UP_NOTIFICATION GEN_LATEST // In Gen9+, if the Pokémon gets enough experience to level up multiple times, the message is only displayed once.
// Stat settings
#define B_BADGE_BOOST GEN_LATEST // In Gen4+, Gym Badges no longer boost a Pokémon's stats.
@ -128,9 +128,9 @@
#define B_QUASH_TURN_ORDER GEN_LATEST // In Gen8+, Quash-affected battlers move according to speed order. Before Gen8, Quash-affected battlers move in the order they were affected by Quash.
#define B_DESTINY_BOND_FAIL GEN_LATEST // In Gen7+, Destiny Bond fails if used repeatedly.
#define B_PURSUIT_TARGET GEN_LATEST // In Gen4+, Pursuit attacks a switching opponent even if they weren't targeting them. Before Gen4, Pursuit only attacks a switching opponent that it originally targeted.
#define B_SKIP_RECHARGE GEN_LATEST // In Gen1, recharging moves such as Hyper Beam skip the recharge if the target gets KO'd
// Ability settings
#define B_ABILITY_WEATHER GEN_LATEST // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability.
#define B_GALE_WINGS GEN_LATEST // In Gen7+ requires full HP to trigger.
#define B_STANCE_CHANGE_FAIL GEN_LATEST // In Gen7+, Stance Change fails if the Pokémon is unable to use a move because of confusion, paralysis, etc. In Gen6, it doesn't.
#define B_SHADOW_TAG_ESCAPE GEN_LATEST // In Gen4+, if both sides have a Pokémon with Shadow Tag, all battlers can escape. Before, neither side could escape this situation.
@ -147,7 +147,6 @@
#define B_REDIRECT_ABILITY_IMMUNITY GEN_LATEST // In Gen5+, Pokémon with Lightning Rod/Storm Drain become immune to Electric/Water-type moves and increase their Sp. Attack by 1 stage on top of the redirecting effect.
#define B_REDIRECT_ABILITY_ALLIES GEN_LATEST // In Gen4+, Lightning Rod/Storm Drain redirect ally's moves as well.
#define B_LEAF_GUARD_PREVENTS_REST GEN_LATEST // In Gen5+, Leaf Guard prevents the use of Rest in harsh sunlight.
#define B_SNOW_WARNING GEN_LATEST // In Gen9+, Snow Warning will summon snow instead of hail.
#define B_TRANSISTOR_BOOST GEN_LATEST // In Gen9+, Transistor will only boost Electric-type moves by 1.3x as opposed to 1.5x.
#define B_ILLUMINATE_EFFECT GEN_LATEST // In Gen9+, Illuminate prevents accuracy reductions and ignores the target's evasion.
#define B_WEAK_ARMOR_SPEED GEN_LATEST // In Gen7+, Weak Armor raises Speed by 2 stages instead of 1 when hit by a physical move.
@ -160,6 +159,8 @@
// In Gen4, it's 30%. In Gen5+ it has 11% to sleep, 9% chance to poison and 10% chance to paralyze.
#define B_PICKUP_WILD GEN_LATEST // In Gen9+, Pickup allows its user to pickup its own used item at the end of the turn in wild battles.
#define B_MAGIC_GUARD GEN_LATEST // In Gen4 only, Magic Guard ignores immobilization caused by paralysis
#define B_BATTLE_BOND GEN_LATEST // In Gen9+, Battle Bond increases Atk, SpAtk and Speed by one stage, once per battle
#define B_ATE_MULTIPLIER GEN_LATEST // In Gen7+, -ate abilities (Aerilate, Galvanize, Normalize, Pixilate, Refrigerate) multiply damage by 1.2. Otherwise, it's 1.3, except Normalize which has no multiplier.
// Item settings
#define B_HP_BERRIES GEN_LATEST // In Gen4+, berries which restore HP activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn.
@ -189,11 +190,19 @@
#define B_IRON_BALL GEN_LATEST // In Gen5+, Flying-type Pokemon holding Iron Ball take x1 damage from Ground-type moves regardless of their other types, except during Inverse Battles or if the Pokemon is grounded by any other effect.
// Flag settings
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to.
// Eg: Replace with FLAG_UNUSED_0x264 so you can use that flag to toggle the feature.
// To use the following features, change the 0 for a flag present in include/constants/flags.h, preferably an unused one.
// Eg: You may rename FLAG_UNUSED_0x264 to a descriptive name and use it below.
// Badge boost flags
#define B_FLAG_BADGE_BOOST_ATTACK FLAG_BADGE01_GET // If this flag is set and B_BADGE_BOOST == GEN_3, it will multiply the player's Pokémon's Attack by x1.1
#define B_FLAG_BADGE_BOOST_DEFENSE FLAG_BADGE05_GET // If this flag is set and B_BADGE_BOOST == GEN_3, it will multiply the player's Pokémon's Defense by x1.1
#define B_FLAG_BADGE_BOOST_SPEED FLAG_BADGE03_GET // If this flag is set and B_BADGE_BOOST == GEN_3, it will multiply the player's Pokémon's Speed by x1.1
#define B_FLAG_BADGE_BOOST_SPATK FLAG_BADGE07_GET // If this flag is set and B_BADGE_BOOST == GEN_3, it will multiply the player's Pokémon's Sp. Atk by x1.1
#define B_FLAG_BADGE_BOOST_SPDEF FLAG_BADGE07_GET // If this flag is set and B_BADGE_BOOST == GEN_3, it will multiply the player's Pokémon's Sp. Def by x1.1
// Other battle flags
#define B_FLAG_INVERSE_BATTLE 0 // If this flag is set, the battle's type effectiveness are inversed. For example, fire is super effective against water.
#define B_FLAG_FORCE_DOUBLE_WILD 0 // If this flag is set, all land and surfing wild battles will be double battles.
#define B_SMART_WILD_AI_FLAG 0 // If not 0, you can set this flag in a script to enable smart wild pokemon
#define B_SMART_WILD_AI_FLAG 0 // If this flag is set, wild Pokémon will become smart, with all AI flags enabled.
#define B_FLAG_NO_BAG_USE 0 // If this flag is set, the ability to use the bag in battle is disabled.
#define B_FLAG_NO_CATCHING 0 // If this flag is set, the ability to catch wild Pokémon is disabled.
#define B_FLAG_NO_RUNNING 0 // If this flag is set, the ability to escape from wild battles is disabled. Also makes Roar/Whirlwind and Teleport (under Gen8) fail.
@ -202,13 +211,18 @@
#define B_FLAG_TERA_ORB_CHARGED 0 // If this flag is set, the Tera Orb is charged. It is automatically set upon healing and cleared upon Terastallizing once configured.
#define B_FLAG_TERA_ORB_NO_COST 0 // If this flag is set, the Tera Orb does not use up its charge upon Terastallization. In S/V, this occurs after an event with Terapagos.
#define B_FLAG_SLEEP_CLAUSE 0 // If this flag is set, sleep clause is enabled; if the player / AI has already put a Pokémon on the opponent's side to sleep and it is still sleeping, another one can't be put to sleep. AI requires AI_FLAG_CHECK_BAD_MOVE to understand.
#define B_FLAG_NO_WHITEOUT 0 // If this flag is set, the player can not white out against Trainers. Please note that the party is not healed automatically!
// Var Settings
// To use the following features in scripting, replace the 0s with the var ID you're assigning it to.
// Eg: Replace with VAR_UNUSED_0x40F7 so you can use B_VAR_STARTING_STATUS for that feature.
// To use the following features, change the 0 for a var present in include/constants/vars.h, preferably an unused one.
// Eg: You may rename VAR_UNUSED_0x404E to a descriptive name and use it below.
#define B_VAR_STARTING_STATUS 0 // If this var has a value, assigning a STATUS_FIELD_xx_TERRAIN to it before battle causes the battle to start with that terrain active.
// This var should never remain non-zero long enough for the player to save.
#define B_VAR_STARTING_STATUS_TIMER 0 // If this var has a value greater or equal than 1 field terrains will last that number of turns, otherwise they will last until they're overwritten.
#define B_VAR_WILD_AI_FLAGS 0 // If not 0, you can use this var to add to default wild AI flags. NOT usable with flags above (1 << 15)
#define B_VAR_WILD_AI_FLAGS 0 // If not 0, you can use this var to add to default wild AI flags. IMPORTANT: NOT usable with flags above (1 << 15)
// This var should never remain non-zero long enough for the player to save.
// For better wild AI handling, edit GetWildAiFlags() in src/battle_ai_main.c
#define B_VAR_DIFFICULTY 0 // If not 0, you can use this var to control which difficulty version of a Trainer is loaded. This should be manually set by the developer using Script_SetDifficulty AFTER NewGameInitData has run.
// Sky Battles
@ -225,6 +239,19 @@
// Move description menu
#define B_SHOW_MOVE_DESCRIPTION TRUE // Shows move information in battler
// Weather settings
// Search for 'rain', 'sunny day', and 'hail' for move-specific or species-specific weather interactions.
#define B_ICE_WEATHER_BOTH 0
#define B_ICE_WEATHER_HAIL 1
#define B_ICE_WEATHER_SNOW 2
#define B_ABILITY_WEATHER GEN_LATEST // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability.
#define B_SANDSTORM_SPDEF_BOOST GEN_LATEST // In Gen4+, Sandstorm weather multiplies the Sp. Defense of Rock-type Pokémon by x1.5.
#define B_OVERWORLD_FOG GEN_LATEST // In Gen8+, overworld Fog summons Misty Terrain in battle. In Gen4 only, overworld Fog summons the unique fog weather condition in battle.
#define B_OVERWORLD_SNOW GEN_LATEST // In Gen9+, overworld Snow will summon snow instead of hail in battle.
#define B_SNOW_WARNING GEN_LATEST // In Gen9+, Snow Warning will summon snow instead of hail.
#define B_PREFERRED_ICE_WEATHER B_ICE_WEATHER_BOTH // Toggles Hail move effects to Snow and vice versa.
// Terrain settings
#define B_TERRAIN_BG_CHANGE TRUE // If set to TRUE, terrain moves permanently change the default battle background until the effect fades.
#define B_THUNDERSTORM_TERRAIN TRUE // If TRUE, overworld Thunderstorm generates Rain and Electric Terrain as in Gen 8.
@ -246,12 +273,18 @@
#define B_HIDE_HEALTHBOX_IN_ANIMS TRUE // If set to TRUE, hides healthboxes during move animations.
#define B_WAIT_TIME_MULTIPLIER 16 // This determines how long text pauses in battle last. Vanilla is 16. Lower values result in faster battles.
#define B_QUICK_MOVE_CURSOR_TO_RUN FALSE // If set to TRUE, pushing B in the battle options against a wild encounter will move the cursor to the run option
#define B_RUN_TRAINER_BATTLE TRUE // If set to TRUE, players can run from Trainer battles. This is treated as a whiteout.
#define B_MOVE_DESCRIPTION_BUTTON L_BUTTON // If set to a button other than B_LAST_USED_BALL_BUTTON, pressing this button will open the move description menu
#define B_SHOW_USELESS_Z_MOVE_INFO FALSE // If set to TRUE, Z-moves without additional effects like newer gen status moves will say "no additional effect"
#define B_ANIMATE_MON_AFTER_KO TRUE // If set to TRUE, if a Pokémon on the opposite site faints, the non-fainted Pokemon will display a victory animation.
#define B_SHOW_DYNAMAX_MESSAGE FALSE // If set to TRUE, an additional battle message is shown after completing Dynamaxing/Gigantamaxing.
// Catching settings
#define B_SEMI_INVULNERABLE_CATCH GEN_LATEST // In Gen4+, you cannot throw a ball against a Pokemon that is in a semi-invulnerable state (dig/fly/etc)
#define B_CATCHING_CHARM_BOOST 20 // % boost in Critical Capture odds if player has the Catching Charm.
#define B_CRITICAL_CAPTURE TRUE // If set to TRUE, Critical Capture will be enabled.
#define B_SEMI_INVULNERABLE_CATCH GEN_LATEST // In Gen4+, you cannot throw a ball against a Pokemon that is in a semi-invulnerable state (dig/fly/etc)
#define B_CATCHING_CHARM_BOOST 20 // % boost in Critical Capture odds if player has the Catching Charm.
#define B_CRITICAL_CAPTURE TRUE // If set to TRUE, Critical Capture will be enabled.
#define B_CRITICAL_CAPTURE_LOCAL_DEX TRUE // If set to FALSE, Critical Capture % is based off of the National Pokedex estimated by enabled generations.
#define B_LAST_USED_BALL TRUE // If TRUE, the "last used ball" feature from Gen 7 will be implemented
#define B_LAST_USED_BALL_BUTTON R_BUTTON // If last used ball is implemented, this button (or button combo) will trigger throwing the last used ball.
#define B_LAST_USED_BALL_CYCLE TRUE // If TRUE, then holding B_LAST_USED_BALL_BUTTON while pressing the D-Pad cycles through the balls
@ -269,12 +302,15 @@
#define B_TRAINER_MON_RANDOM_ABILITY FALSE // If this is set to TRUE a random legal ability will be generated for a trainer mon
#define B_OBEDIENCE_MECHANICS GEN_LATEST // In PLA+ (here Gen8+), obedience restrictions also apply to non-outsider Pokémon, albeit based on their level met rather than actual level
#define B_USE_FROSTBITE FALSE // In PLA, Frostbite replaces Freeze. Enabling this flag does the same here. Moves can still be cherry-picked to either Freeze or Frostbite. Freeze-Dry, Secret Power & Tri Attack depend on this config.
#define B_OVERWORLD_SNOW GEN_LATEST // In Gen9+, overworld Snow will summon snow instead of hail in battle.
#define B_OVERWORLD_FOG GEN_LATEST // In Gen8+, overworld Fog summons Misty Terrain in battle. In Gen4 only, overworld Fog summons the unique fog weather condition in battle.
#define B_TOXIC_REVERSAL GEN_LATEST // In Gen5+, bad poison will change to regular poison at the end of battles.
#define B_TRY_CATCH_TRAINER_BALL GEN_LATEST // In Gen4+, trying to catch a Trainer's Pokémon does not consume the Poké Ball.
#define B_SLEEP_CLAUSE FALSE // Enables Sleep Clause all the time in every case, overriding B_FLAG_SLEEP_CLAUSE. Use that for modularity.
#define NUM_BEEPS_GEN_LATEST 4 // Loops 4 times
#define NUM_BEEPS_GEN_3 -1 // Loops infinitely
#define NUM_BEEPS_OFF 0 // Doesn't play at all
#define B_NUM_LOW_HEALTH_BEEPS NUM_BEEPS_GEN_LATEST // This controls the number of times the "low health" beep will loop. Setting this value to NUM_BEEPS_OFF will disable the beep, while NUM_BEEPS_GEN_3 will loop infinitely. You can set this to any number you want, the defines listed are just for ease of use.
// Animation Settings
#define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle.
#define B_NEW_LEECH_SEED_PARTICLE FALSE // If set to TRUE, it updates Leech Seed's animation particle.
@ -298,10 +334,17 @@
#define B_ENEMY_THROW_BALLS_SOUND GEN_LATEST // In GEN_5+, enemy Trainer's Poké Balls make a sound when thrown to send out a Pokémon. This can only be used when B_ENEMY_THROW_BALLS is set to GEN_6 or later.
#define B_PLAYER_THROW_BALLS_SOUND GEN_LATEST // In GEN_5+, the player's Poké Balls make a sound when thrown to send out a Pokémon.
#define SHOW_TYPES_NEVER 0
#define SHOW_TYPES_ALWAYS 1
#define SHOW_TYPES_CAUGHT 2
#define B_SHOW_TYPES SHOW_TYPES_NEVER // When defined as SHOW_TYPES_ALWAYS, after selecting "Fight" in battle, the types of all Pokemon are revealed. Whe defined as SHOW_TYPES_OWN, types are only revealed if the player owns the mon in question.
#define SHOW_TYPES_NEVER 0 // Never shows types in battle
#define SHOW_TYPES_ALWAYS 1 // Always show types in battle
#define SHOW_TYPES_CAUGHT 2 // Only show types if you've caught a species of the mon.
#define SHOW_TYPES_SEEN 3 // Only show types if you've seen a species of the mon.
#define B_SHOW_TYPES SHOW_TYPES_NEVER // When to show type indicators next to Pokémon health bars in battle, while choosing a move after selecting a target Pokémon.
#define SHOW_EFFECTIVENESS_NEVER 0 // Never show effectiveness when selecting moves.
#define SHOW_EFFECTIVENESS_ALWAYS 1 // Always show effectiveness when selecting moves.
#define SHOW_EFFECTIVENESS_CAUGHT 2 // Only show effectiveness if you've caught a species of the mon.
#define SHOW_EFFECTIVENESS_SEEN 3 // Only show effectiveness if you've seen a species of the mon.
#define B_SHOW_EFFECTIVENESS SHOW_EFFECTIVENESS_SEEN // If not SHOW_EFFECTIVENESS_NEVER, the PP string is replaced by a type effectiveness indicator based off the moves and the opposing side.
// Pokémon battle sprite settings
#define B_ENEMY_MON_SHADOW_STYLE GEN_LATEST // In Gen4+, all enemy Pokemon will have a shadow drawn beneath them.

View File

@ -0,0 +1,13 @@
#ifndef GUARD_FOLLOWER_NPC_OVERWORLD_H
#define GUARD_FOLLOWER_NPC_OVERWORLD_H
// NPC Followers
#define FNPC_ENABLE_NPC_FOLLOWERS FALSE // Enables the use of script macros to designate NPCs to follow behind the player, DPP style. Slightly increases the size of the saveblock (SaveBlock3).
#define FNPC_FLAG_HEAL_AFTER_FOLLOWER_BATTLE 0 // Replace the 0 with a flag in order to use that flag to toggle whether the Player's party will be automatically healed after every follower partner battle. If you want this to always be active without using a flag, replace 0 with FNPC_ALWAYS.
#define FNPC_FLAG_PARTNER_WILD_BATTLES 0 // Replace the 0 with a flag in order to use that flag to toggle whether the follower partner will join you for wild battles. If you want this to always be active without using a flag, replace 0 with FNPC_ALWAYS.
#define FNPC_NPC_FOLLOWER_WILD_BATTLE_VS_2 TRUE // If set to TRUE, two wild Pokemon will show up to the partner battle instead of just one.
#define FNPC_NPC_FOLLOWER_PARTY_PREVIEW TRUE // If set to TRUE, a preview of the player's and partner's teams will be shown before every trainer battle.
#define FNPC_FACE_NPC_FOLLOWER_ON_DOOR_EXIT TRUE // If set to TRUE, the player will turn to face the follower when they exit a doorway.
#define FNPC_NPC_FOLLOWER_SHOW_AFTER_LEAVE_ROUTE TRUE // If set to TRUE, the follower will reappear and walk out of the player after using Fly, Escape Rope, or Teleport.
#endif // GUARD_FOLLOWER_NPC_OVERWORLD_H

View File

@ -68,14 +68,12 @@
// General settings
#define EXPANSION_INTRO TRUE // If TRUE, a custom RHH intro will play after the vanilla copyright screen.
#define POKEDEX_PLUS_HGSS FALSE // If TRUE, enables the custom HGSS style Pokedex.
#define SUMMARY_SCREEN_NATURE_COLORS TRUE // If TRUE, nature-based stat boosts and reductions will be red and blue in the summary screen.
#define HQ_RANDOM TRUE // If TRUE, replaces the default RNG with an implementation of SFC32 RNG. May break code that relies on RNG.
#define COMPETITIVE_PARTY_SYNTAX TRUE // If TRUE, parties are defined in "competitive syntax".
#define AUTO_SCROLL_TEXT FALSE // If TRUE, text will automatically scroll to the next line after NUM_FRAMES_AUTO_SCROLL_DELAY. Players can still press A_BUTTON or B_BUTTON to scroll on their own.
#define NUM_FRAMES_AUTO_SCROLL_DELAY 49
// Measurement system constants to be used for UNITS
#define UNITS_IMPERIAL 0 // Inches, feet, pounds
#define UNITS_METRIC 1 // meters, kilograms

View File

@ -10,6 +10,7 @@
#define OW_DOUBLE_APPROACH_WITH_ONE_MON FALSE // If enabled, you can be spotted by two trainers at the same time even if you only have one eligible Pokémon in your party.
#define OW_HIDE_REPEAT_MAP_POPUP FALSE // If enabled, map popups will not appear if entering a map with the same Map Section Id as the last.
#define OW_FRLG_WHITEOUT FALSE // If enabled, shows an additional whiteout message and post whiteout event script with healing NPC.
#define OW_DEFOG_FIELD_MOVE FALSE // If enabled, Defog can be used as a Field Move as seen in DPPt.
// Item Obtain Description Box
#define OW_ITEM_DESCRIPTIONS_OFF 0 // never show descriptions
@ -61,31 +62,13 @@
#define OW_FOLLOWERS_COPY_WILD_PKMN FALSE // If TRUE, follower Pokémon that know Transform or have Illusion/Imposter will copy wild Pokémon at random.
#define OW_BATTLE_ONLY_FORMS TRUE // If TRUE, loads overworld sprites for battle-only forms like Mega Evos. Requires OW_POKEMON_OBJECT_EVENTS.
#define B_FLAG_FOLLOWERS_DISABLED 0 // Enables / Disables followers by using a flag. Helpful to disable followers for a period of time.
#define OW_FOLLOWERS_SCRIPT_MOVEMENT TRUE // TRUE: Script collisions hide follower, FLAG_SAFE_FOLLOWER_MOVEMENT on by default
// FALSE: Script collisions unhandled, FLAG_SAFE_FOLLOWER_MOVEMENT off by default
// If set, the only pokemon allowed to follow you
// will be those matching species, met location,
// and/or met level;
// These accept vars, too: VAR_TEMP_1, etc
#define OW_MON_ALLOWED_SPECIES (0)
#define OW_MON_ALLOWED_MET_LVL (0)
#define OW_MON_ALLOWED_MET_LOC (0)
// Examples:
// Yellow Pikachu:
// #define OW_MON_ALLOWED_SPECIES (SPECIES_PIKACHU)
// #define OW_MON_ALLOWED_MET_LVL (0)
// #define OW_MON_ALLOWED_MET_LOC (MAPSEC_PALLET_TOWN)
// Hoenn Starter:
// #define OW_MON_ALLOWED_SPECIES (0)
// #define OW_MON_ALLOWED_MET_LVL (5)
// #define OW_MON_ALLOWED_MET_LOC (MAPSEC_ROUTE_101)
// Species set in VAR_XXXX:
// #define OW_MON_ALLOWED_SPECIES (VAR_XXXX)
// #define OW_MON_ALLOWED_MET_LVL (0)
// #define OW_MON_ALLOWED_MET_LOC (0)
#define OW_FOLLOWERS_SCRIPT_MOVEMENT TRUE // If TRUE, follower Pokémon only go back to their Poké Ball if a non-player collides with them by setting the FLAG_SAFE_FOLLOWER_MOVEMENT flag by default.
// Follower Pokémon Restrictions
// If set, the only pokemon allowed to follow you will be those matching species, met location, and/or met level; These accept vars, too: VAR_TEMP_1, etc
// For examples, see "docs/tutorials/how_to_new_pokemon.md"
#define OW_FOLLOWERS_ALLOWED_SPECIES (0)
#define OW_FOLLOWERS_ALLOWED_MET_LVL (0)
#define OW_FOLLOWERS_ALLOWED_MET_LOC (0)
// Out-of-battle Ability effects
#define OW_SYNCHRONIZE_NATURE GEN_LATEST // In Gen8+, if a Pokémon with Synchronize leads the party, wild Pokémon will always have their same Nature as opposed to the 50% chance in previous games. Gift Pokémon excluded.
@ -98,13 +81,25 @@
#define OW_STORM_DRAIN GEN_LATEST // In Gen8+, if a Pokémon with Storm Drain is leading the party, there is a 50% chance to encounter a Water-type Pokémon.
#define OW_FLASH_FIRE GEN_LATEST // In Gen8+, if a Pokémon with Flash Fire is leading the party, there is a 50% chance to encounter a Fire-type Pokémon.
// These generational defines only make a distinction for OW_ALTERED_TIME_RATIO
// These defines only make a distinction for OW_ALTERED_TIME_RATIO
#define GEN_8_PLA GEN_LATEST + 2
#define TIME_DEBUG GEN_LATEST + 3
//Time
#define OW_TIMES_OF_DAY GEN_LATEST // Different generations have the times of day change at different times.
#define OW_USE_FAKE_RTC FALSE // When TRUE, seconds on the in-game clock will only advance once every 60 playTimeVBlanks (every 60 frames).
#define OW_ALTERED_TIME_RATIO GEN_LATEST // In GEN_8_PLA, the time in game moves forward 60 seconds for every second in the RTC. In GEN_9, it is 20 seconds. This has no effect if OW_USE_FAKE_RTC is FALSE.
#define OW_TIMES_OF_DAY GEN_LATEST // Different generations have the times of day change at different times.
#define OW_USE_FAKE_RTC FALSE // When TRUE, seconds on the in-game clock will only advance once every 60 playTimeVBlanks (every 60 frames).
#define OW_ALTERED_TIME_RATIO GEN_LATEST // In GEN_8_PLA, the time in game moves forward 60 seconds for every second in the RTC. In GEN_9, it is 20 seconds. TIME_DEBUG is 1:1, and meant for debugging purposes. This has no effect if OW_USE_FAKE_RTC is FALSE.
#define OW_TIME_OF_DAY_ENCOUNTERS FALSE // If TRUE, will allow the user to define and use different encounter tables based on the time of day.
#define OW_TIME_OF_DAY_DISABLE_FALLBACK FALSE // If TRUE, if the encounter table for a specific map and time is empty, the area will have no encounters instead of falling back to the vanilla map and time.
#define OW_TIME_OF_DAY_FALLBACK TIME_MORNING // The time of day that encounter tables fall back to.
// Lighting
#define OW_SHADOW_INTENSITY 4 // Ranges from 0 to 16, where 0 is fully transparent and 16 is black.
#define OW_OBJECT_SUBPRIORITY 148 // The higher the value, the farther back compared to other sprites. Shadows should be behind object events.
#define OW_ENABLE_DNS TRUE // If set to TRUE, the overworld will be tinted depending on time of day.
// Object Event Shadows
#define OW_OBJECT_VANILLA_SHADOWS FALSE // In vanilla shadows in the overworld are only shown when jumping.
// Overworld flags
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to.
@ -119,7 +114,9 @@
// Map pop-up config
#define OW_POPUP_GENERATION GEN_3 // Different generations display location names in overworld pop-ups differently.
// Only choices are currently GEN_3 and GEN_5, all others will default to Gen3 pop-ups.
// Only choices are GEN_3 and GEN_5, all others will default to Gen3 pop-ups.
// Due to changes in project scope, as detailed in docs/team_procedures/scope.md,
// no other overworld popups will be implemented in expansion.
// Gen5 map pop-up config
// Constants
@ -134,6 +131,7 @@
#define OW_POPUP_BW_COLOR OW_POPUP_BW_COLOR_BLACK // B2W2 use different colors for their map pop-ups.
#define OW_POPUP_BW_TIME_MODE OW_POPUP_BW_TIME_NONE // Determines what type of time is shown.
#define OW_POPUP_BW_ALPHA_BLEND FALSE // Enables alpha blending/transparency for the pop-ups. Mainly intended to be used with the black color option.
// Setting this to TRUE will cause graphical errors with the Day Night System enabled.
// Pokémon Center
#define OW_IGNORE_EGGS_ON_HEAL GEN_LATEST // In Gen 4+, the nurse in the Pokémon Center does not heal Eggs on healing machine.

View File

@ -0,0 +1,11 @@
#ifndef GUARD_CONFIG_POKEDEX_PLUS_HGSS_H
#define GUARD_CONFIG_POKEDEX_PLUS_HGSS_H
#define POKEDEX_PLUS_HGSS FALSE // If TRUE, enables the custom HGSS style Pokedex.
#define HGSS_DECAPPED FALSE // If TRUE, uses decapped gfx and strings.
#define HGSS_DARK_MODE FALSE // If TRUE, enables dark mode.
#define HGSS_HIDE_UNSEEN_EVOLUTION_NAMES FALSE // If TRUE, hides evolution mon names.
#define HGSS_SORT_TMS_BY_NUM FALSE // If TRUE, sorts the TMS in HGSS Dex by TM number, rather than alphabetically.
#define HGSS_SHOW_EGG_MOVES_FOR_EVOS FALSE // If TRUE, shows Egg Moves for evolved Pokémon too.
#endif // GUARD_CONFIG_POKEDEX_PLUS_HGSS_H

View File

@ -62,7 +62,8 @@
#define P_SHOW_DYNAMIC_TYPES FALSE // If TRUE, all moves with dynamic type changes will be reflected as their current type in battle/summary screens instead of just select ones like in vanilla.
// Learnset helper toggles
#define P_LEARNSET_HELPER_TEACHABLE TRUE // If TRUE, teachable_learnsets.h will be populated by tools/learnset_helpers/teachable.py using the included JSON files based on available TMs and tutors.
#define P_LEARNSET_HELPER_TEACHABLE TRUE // If TRUE, teachable_learnsets.h will be populated by tools/learnset_helpers/make_teachables.py using the included JSON files based on available TMs and tutors.
#define P_TUTOR_MOVES_ARRAY FALSE // If TRUE, generates a gTutorMoves array automatically using make_teachables.py. (generally not needed, but the HGSS Pokedex has an optional use for it)
// Flag settings
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to.

View File

@ -1139,4 +1139,7 @@
#undef B_FLAG_INVERSE_BATTLE
#define B_FLAG_INVERSE_BATTLE TESTING_FLAG_INVERSE_BATTLE
// Move animation testing
#define T_SHOULD_RUN_MOVE_ANIM FALSE // If TRUE, enables the move animation tests, these are very computationally heavy and takes a long time to run.
#endif // GUARD_CONFIG_TEST_H

View File

@ -183,10 +183,10 @@ enum BattlerId
#define STATUS3_GASTRO_ACID (1 << 16)
#define STATUS3_EMBARGO (1 << 17)
#define STATUS3_UNDERWATER (1 << 18)
#define STATUS3_INTIMIDATE_POKES (1 << 19)
#define STATUS3_TRACE (1 << 20)
#define STATUS3_UNUSED_19 (1 << 19)
#define STATUS3_UNUSED_20 (1 << 20)
#define STATUS3_SMACKED_DOWN (1 << 21)
#define STATUS3_ME_FIRST (1 << 22)
#define STATUS3_UNUSED_22 (1 << 22)
#define STATUS3_TELEKINESIS (1 << 23)
#define STATUS3_PHANTOM_FORCE (1 << 24)
#define STATUS3_MIRACLE_EYED (1 << 25)
@ -217,7 +217,7 @@ enum BattlerId
#define HITMARKER_NO_PPDEDUCT (1 << 11)
#define HITMARKER_UNUSED_2 (1 << 12)
#define HITMARKER_STATUS_ABILITY_EFFECT (1 << 13)
#define HITMARKER_SYNCHRONISE_EFFECT (1 << 14)
#define HITMARKER_SYNCHRONIZE_EFFECT (1 << 14)
#define HITMARKER_RUN (1 << 15)
#define HITMARKER_IGNORE_DISGUISE (1 << 16)
#define HITMARKER_DISABLE_ANIMATION (1 << 17) // disable animations during battle scripts, e.g. for Bug Bite
@ -229,7 +229,7 @@ enum BattlerId
#define HITMARKER_ALLOW_NO_PP (1 << 23)
#define HITMARKER_GRUDGE (1 << 24)
#define HITMARKER_OBEYS (1 << 25)
#define HITMARKER_NEVER_SET (1 << 26) // Cleared as part of a large group. Never set or checked
#define HITMARKER_UNUSED_5 (1 << 26)
#define HITMARKER_CHARGING (1 << 27)
#define HITMARKER_FAINTED(battler) (1u << (battler + 28))
#define HITMARKER_FAINTED2(battler) HITMARKER_FAINTED(battler)
@ -250,15 +250,11 @@ enum BattlerId
#define SIDE_STATUS_TOXIC_SPIKES (1 << 13)
#define SIDE_STATUS_STEALTH_ROCK (1 << 14)
// Missing flags previously were SIDE_STATUS_TOXIC_SPIKES_DAMAGED, SIDE_STATUS_STEALTH_ROCK_DAMAGED, SIDE_STATUS_STICKY_WEB_DAMAGED
#define SIDE_STATUS_QUICK_GUARD (1 << 18)
#define SIDE_STATUS_WIDE_GUARD (1 << 19)
#define SIDE_STATUS_CRAFTY_SHIELD (1 << 20)
#define SIDE_STATUS_MAT_BLOCK (1 << 21)
#define SIDE_STATUS_STEELSURGE (1 << 22)
#define SIDE_STATUS_DAMAGE_NON_TYPES (1 << 23)
#define SIDE_STATUS_RAINBOW (1 << 24)
#define SIDE_STATUS_SEA_OF_FIRE (1 << 25)
#define SIDE_STATUS_SWAMP (1 << 26)
#define SIDE_STATUS_STEELSURGE (1 << 18)
#define SIDE_STATUS_DAMAGE_NON_TYPES (1 << 19)
#define SIDE_STATUS_RAINBOW (1 << 20)
#define SIDE_STATUS_SEA_OF_FIRE (1 << 21)
#define SIDE_STATUS_SWAMP (1 << 22)
#define SIDE_STATUS_HAZARDS_ANY (SIDE_STATUS_SPIKES | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES | SIDE_STATUS_STEALTH_ROCK | SIDE_STATUS_STEELSURGE)
#define SIDE_STATUS_SCREEN_ANY (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL)
@ -389,10 +385,8 @@ enum MoveEffects
MOVE_EFFECT_EVS_MINUS_2,
MOVE_EFFECT_SCALE_SHOT,
MOVE_EFFECT_THRASH,
MOVE_EFFECT_KNOCK_OFF,
MOVE_EFFECT_DEF_SPDEF_DOWN,
MOVE_EFFECT_CLEAR_SMOG,
MOVE_EFFECT_SMACK_DOWN,
MOVE_EFFECT_FLAME_BURST,
MOVE_EFFECT_FEINT,
MOVE_EFFECT_V_CREATE,
@ -404,7 +398,6 @@ enum MoveEffects
MOVE_EFFECT_RECOIL_HP_25,
MOVE_EFFECT_TRAP_BOTH,
MOVE_EFFECT_ROUND,
MOVE_EFFECT_STOCKPILE_WORE_OFF,
MOVE_EFFECT_DIRE_CLAW,
MOVE_EFFECT_STEALTH_ROCK,
MOVE_EFFECT_SPIKES,

View File

@ -30,19 +30,25 @@
#define AI_FLAG_PREFER_HIGHEST_DAMAGE_MOVE (1 << 22) // AI adds score to highest damage move regardless of accuracy or secondary effect
#define AI_FLAG_PREDICT_SWITCH (1 << 23) // AI will predict the player's switches and switchins based on how it would handle the situation. Recommend using AI_FLAG_OMNISCIENT
#define AI_FLAG_PREDICT_INCOMING_MON (1 << 24) // AI will score against the predicting incoming mon if it predicts the player to switch. Requires AI_FLAG_PREDICT_SWITCH
#define AI_FLAG_PP_STALL_PREVENTION (1 << 25) // AI keeps track of the player's switches where the incoming mon is immune to the chosen move
#define AI_FLAG_PREDICT_MOVE (1 << 26) // AI will predict the player's move based on what move it would use in the same situation. Recommend using AI_FLAG_OMNISCIENT
#define AI_FLAG_COUNT 25
// Flags at and after 32 need different formatting, as in
// #define AI_FLAG_PLACEHOLDER ((u64)1 << 32)
#define AI_FLAG_COUNT 27
// The following options are enough to have a basic/smart trainer. Any other addtion could make the trainer worse/better depending on the flag
#define AI_FLAG_BASIC_TRAINER (AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY)
#define AI_FLAG_SMART_TRAINER (AI_FLAG_BASIC_TRAINER | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_WEIGH_ABILITY_PREDICTION)
#define AI_FLAG_PREDICTION (AI_FLAG_PREDICT_SWITCH | AI_FLAG_PREDICT_INCOMING_MON)
#define AI_FLAG_PREDICTION (AI_FLAG_PREDICT_SWITCH | AI_FLAG_PREDICT_INCOMING_MON | AI_FLAG_PREDICT_MOVE)
// 'other' ai logic flags
#define AI_FLAG_DYNAMIC_FUNC (1 << 28) // Create custom AI functions for specific battles via "setdynamicaifunc" cmd
#define AI_FLAG_ROAMING (1 << 29)
#define AI_FLAG_SAFARI (1 << 30)
#define AI_FLAG_FIRST_BATTLE (1 << 31)
#define AI_FLAG_DYNAMIC_FUNC ((u64)1 << 60) // Create custom AI functions for specific battles via "setdynamicaifunc" cmd
#define AI_FLAG_ROAMING ((u64)1 << 61)
#define AI_FLAG_SAFARI ((u64)1 << 62)
#define AI_FLAG_FIRST_BATTLE ((u64)1 << 63)
#define AI_SCORE_DEFAULT 100 // Default score for all AI moves.

View File

@ -506,9 +506,9 @@
#define BG_BOLT_STRIKE 55
#define BG_ZMOVE_ACTIVATE 56
#define BG_TECTONIC_RAGE 57
#define BG_BLUE_SKY_DAY 58
#define BG_BLUE_SKY_AFTERNOON 59
#define BG_BLUE_SKY_NIGHT 60
#define BG_ROCK_FIELD_DAY 58
#define BG_ROCK_FIELD_AFTERNOON 59
#define BG_ROCK_FIELD_NIGHT 60
#define BG_ZMOVE_MOUNTAIN 61
#define BG_NEVERENDING_NIGHTMARE 62
#define BG_WATER_PULSE 63
@ -586,8 +586,9 @@
#define B_ANIM_TERA_CHARGE 50
#define B_ANIM_TERA_ACTIVATE 51
#define B_ANIM_SIMPLE_HEAL 52
#define B_ANIM_POWER_CONSTRUCT 53
#define NUM_B_ANIMS_GENERAL 53
#define NUM_B_ANIMS_GENERAL 54
// special animations table (sBattleAnims_Special)
#define B_ANIM_LVL_UP 0

View File

@ -1,10 +1,11 @@
#ifndef GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H
#define GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H
enum {
enum BattleMoveEffects
{
EFFECT_PLACEHOLDER,
EFFECT_HIT,
EFFECT_SLEEP,
EFFECT_NON_VOLATILE_STATUS,
EFFECT_ABSORB,
EFFECT_EXPLOSION,
EFFECT_DREAM_EATER,
@ -30,7 +31,6 @@ enum {
EFFECT_MULTI_HIT,
EFFECT_CONVERSION,
EFFECT_RESTORE_HP,
EFFECT_TOXIC,
EFFECT_LIGHT_SCREEN,
EFFECT_REST,
EFFECT_OHKO,
@ -58,8 +58,6 @@ enum {
EFFECT_ACCURACY_DOWN_2,
EFFECT_EVASION_DOWN_2,
EFFECT_REFLECT,
EFFECT_POISON,
EFFECT_PARALYZE,
EFFECT_TWO_TURNS_ATTACK,
EFFECT_SUBSTITUTE,
EFFECT_RAGE,
@ -123,7 +121,6 @@ enum {
EFFECT_EARTHQUAKE,
EFFECT_FUTURE_SIGHT,
EFFECT_SOLAR_BEAM,
EFFECT_THUNDER,
EFFECT_TELEPORT,
EFFECT_BEAT_UP,
EFFECT_SEMI_INVULNERABLE,
@ -138,7 +135,6 @@ enum {
EFFECT_HAIL,
EFFECT_TORMENT,
EFFECT_FLATTER,
EFFECT_WILL_O_WISP,
EFFECT_MEMENTO,
EFFECT_FACADE,
EFFECT_FOCUS_PUNCH,
@ -336,8 +332,6 @@ enum {
EFFECT_FILLET_AWAY,
EFFECT_IVY_CUDGEL,
EFFECT_FICKLE_BEAM,
EFFECT_BLIZZARD,
EFFECT_RAIN_ALWAYS_HIT, // Unlike EFFECT_THUNDER, it doesn't get its accuracy reduced under sun.
EFFECT_SHED_TAIL,
EFFECT_UPPER_HAND,
EFFECT_DRAGON_CHEER,
@ -352,6 +346,8 @@ enum {
EFFECT_ORDER_UP,
EFFECT_RAPID_SPIN,
EFFECT_SPECTRAL_THIEF,
EFFECT_RECOIL,
EFFECT_SMACK_DOWN,
NUM_BATTLE_MOVE_EFFECTS,
};

Some files were not shown because too many files have changed in this diff Show More