Bienvenue visiteur !
|

Statistiques
Liste des membres
Contact
Mentions légales
78 connectés actuellement
31088317 visiteurs depuis l'ouverture
1086 visiteurs aujourd'hui

Partenaires







Tous nos partenaires
Devenir partenaire
|
Messages postés par mugen808 Nombre de messages référencés sur Oniromancie (non supprimés): 6 Aller à la page: 1
Posté dans Forum - [MV] 808 Pre-Battle System (Fréquence, tri ennemis, transition) |
mugen808 -
posté le 27/10/2024 à 19:56:36. (6 messages postés) |
| Je vous propose un petit set de 3 plugins qui ont trait aux combats dans MV. Il ne s’agit pas d’un système de combat, ils agissent plutôt sur les étapes qui précèdent le combat.
C’est un set de trois plugins qui peuvent tous fonctionner seuls ou ensemble.
Par ordre de chargement dans la liste des plugins (du haut vers le bas) :
1) 808troopCondition.js
Un plugin qui permet de filtrer les troupes ennemies qu’il est possible de rencontrer selon divers paramètres.
2) 808BattleFrequency.js
Une autre façon gérer la fréquence de combats aléatoire, notamment en incluant la différence entre le niveau du groupe et la dangerosité de la zone traversée.
3) 808BattleTransition.js
Un effet de transition façon fragmentation et éclatement de l’écran au moment ou un combat se déclenche.
Les trois plugins se trouvent tout en bas de ce post.
Dans le détail :
-808troopCondition
Spoiler (cliquez pour afficher) L’intérêt de ce plugin est de donner plus de souplesse aux conditions de rencontre de groupes d’ennemis spécifiques, selon la région ou le terrain traversé ou encore le niveau moyen du groupe.
Cela peut s’appliquer pour un type de créatures qui n’apparait que sur l’eau peu profonde par exemple.
Mais aussi sur une carte très large sur laquelle beaucoup d’ennemis de niveaux différents coexistent, comme une carte du monde par exemple.
On peut par exemple couper la carte en zone distinctes par niveau (les monstres forts sur les régions 1 à 10 et les monstres moyens en zone 11 à 20 par exemple).
MV accepte déjà les régions pour les monstres mais limité à 3 régions uniquement. Quant aux terrains ou au niveau du groupe, ces conditions ne sont pas disponibles.
Fonctionnement :
Dans l’onglet troupes de MV, dans la première page de l’évènement de troupe, insérez un commentaire avec les tags appropriés :
<region: 1, 5-7>
Dans ce cas, les groupe d’ennemi n’apparaitra que lorsque le joueur traverse les régions 1, 5, 6, 7.
<terrain: 3>
Les ennemis sur la page desquels se trouve ce commentaire ne pourront être rencontrés que lorsque le joueur traverse une case avec le terrain ID 3.
<terrain: 2-4>
Les ennemis sur la page desquels se trouve ce commentaire ne pourront être rencontrés que lorsque le joueur traverse une case avec le terrain ID 2 ou 3 ou 4.
<plevel: 80-99>
Le groupe d’ennemis ainsi tagué ne pourra surgir que si l’équipe est en moyenne d’un niveau compris entre 80 et 99.
Si aucun des tags ci-dessus n’est présent, le groupe ennemi non tagué sera géré par le moteur d’origine de RPG Maker MV. C’est-à-dire :
Troupe ID1 = Molosse *1
Je ne mets aucun commentaire au molosse.
Troupe ID 2 = Squelette *1
Je marque le Squelette avec un commentaire : <region : 6>
Troupe ID 3 = Dragonnet *1
J’insère en commentaire <region : 4-6>
<plevel : 10-99>
Je place le joueur sur une carte qui est peinte avec un mix de « pas de région », et de cases peintes avec les régions 1 à 5.
Dans les propriétés de cette carte, je liste les troupes ennemies qui peuvent être croisées. ID 1 + 2
+ 3
Je donne à chacune le même poids 10, et je paramètre leur présence possible sur la carte entière.
-Le Molosse sera susceptible d’apparaitre à chaque rencontre car il n’a aucun commentaire.
-Le Squelette n’apparaitra jamais, parce qu’il ne se rencontre que lorsque le joueur est sur la région 6 qui n’existe pas sur ma carte.
-Le Dragonnet quant a lui se rencontrera sur les cases de région 4 ou 5, à condition que le groupe soit de niveau 10 ou plus.
Le poids des troupes est pris en compte dans les probabilités d’apparition depuis les propriétés de la carte, la méthode par défaut est conservée sur ce point.
-808BattleFrequency
Spoiler (cliquez pour afficher) Un plugin qui modifie la fréquence des combats aléatoires en rendant la probabilité très faible lors des premiers pas et de plus en plus importante au fur et a mesure que de nouveaux déplacements sont effectués sans avoir de combat aléatoire.
Le niveau des joueurs est aussi pris en compte et la fréquence s’en trouve diminué quand le groupe est trop fort pour la région traversée, ou augmentée lorsque le groupe se trouve dans une zone de plus haut niveau.
En gros, un compteur de danger augmente à chaque pas « compté ».
Le compteur de danger est remis à zéro en entrant sur une nouvelle carte ou après un combat.
Il peut aussi être remis à zéro au besoin avec une commande de plugin :
BattleFrequency reset
La valeur de la probabilité de rencontre aléatoire varie en fonction de ce compteur (et donc du nombre de pas) ainsi que du modificateur de zone (influencé par la différence entre le niveau de danger la zone traversée et le niveau du groupe).
A chaque contrôle de fréquence, un nombre aléatoire est généré. Si ce nombre est inférieur à la probabilité de rencontre, un combat se déclenche.
Le paramètre Step Check Interval (valeur de 1 par défaut) correspond au nombre de pas entre lesquels un contrôle est effectué. Quand sa valeur est de 1, le moteur contrôlera si un combat a lieu à chaque pas. Si sa valeur est de 2, la probabilité d’un combat sera effectuée lors d’un pas sur deux.
Les cartes peuvent éventuellement être taguées dans le champ Note avec un Step Check comme ceci :
<stepCheck 2>
Avec ce tag, les rencontres sur cette carte ne seront possibles qu’une fois tous les deux pas.
Si la carte comporte cette note, elle prendra le pas sur la valeur du paramètre de plugin Step Check.
En d’autres termes, le paramètre de Step Check n’est utile que sur les cartes qui n’ont pas de Step check note.
L’intérêt de cette fonction est de changer la fréquence donnée pour un certain nombre de pas. Cela peut être utile dans certains cas :
Par exemple, une map sur laquelle le héros se déplace plus vite. A ce moment-là, le paramètre de plugin pourrait être de 1 et le tag de la carte de 2, pour équilibrer la fréquence de combat sur la carte ou le héros se déplace plus vite.
Ou encore, sur une carte qui utilise le déplacement de base de MV (un pas = 1 case), le Step Check sera de 1. Et sur d’autre cartes avec un pixel mouvement, par exemple qui permet de se déplacer à l’intérieur d’une case en 3 ou 4 pas, on donnera a cette carte un Step Check de 3 ou 4 pour ramener la fréquence de combat au même niveau que la carte du monde, soit un check par case.
Les cartes aussi doivent impérativement être taguées dans leur champs Note avec la valeur de la Zone de Danger.
On peut rentrer une valeur fixe si elle est bonne pour toute la carte. Par exemple dans un donjon de niveau 10 :
<zoneDanger 10>
Ou alors on peut utiliser les régions comme zone de danger avec:
<zoneDanger region>
A ce moment-là, en marchant sur la région 14, la fréquence de combat sera calculée pour une zone de niveau 14, le temps du passage sur cette case.
Attention, si la carte n’est pas marquée avec une valeur de Zone de Danger, aucune rencontre aléatoire n’aura lieu, puisque la zone de danger sera considérée comme ayant une valeur de 0 et introduira cette valeur dans la formula de rencontre aléatoire.
Voici l’effet que les différences entre niveau du groupe et niveau de la zone de danger auront sur la formule de rencontres :
Petite différence de niveau (Équipe de niveau 3 dans une zone de niveau 2) :
• levelDiff = -1
• weightFactor ≈ 0,10
• dangerModifier ≈ 0,97
• Résultat : 97 % du taux de rencontres normal
Différence de niveau moyenne (Équipe de niveau 50 dans une zone de niveau 45) :
• levelDiff = -5
• weightFactor ≈ 0,25
• dangerModifier ≈ 0,94
• Résultat : 94 % du taux de rencontres normal
Grande différence de niveau (Équipe de niveau 3 dans une zone de niveau 99) :
• levelDiff = 96
• weightFactor ≈ 19,13
• dangerModifier = 4,0 (capé par la limite)
• Résultat : 400 % du taux de rencontres normal
Différence de niveau extrême (Équipe de niveau 99 dans une zone de niveau 3) :
• levelDiff = -96
• weightFactor ≈ 19,13
• dangerModifier = 0,25 (capé par la limite)
• Résultat : 25 % du taux de rencontres normal
-808BattleTransition
Celui-ci est tout simple ! Il s’agit d’un effet de morcellement de l’écran au moment ou un combat se lance, pour une transition un peu plus stylée que l’écran blanc d’origine.
Codes à insérer dans un document texte, à renommer en .js et à placer dans le projet dans jsplugins:
A renommer 808TroopCondition.js:
Spoiler (cliquez pour afficher)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
| // File: 808TroopCondition.js
/*:
* @plugindesc v1.3 Enhanced troop encounter selection with region, terrain, and party level filters.
* @version 1.3
* @author mugen808
*
* @param Debug
* @type boolean
* @desc Set to true to enable console logs for debugging.
* @default false
*
* @help
* This plugin enhances troop selection by applying conditional filters based on
* map regions, terrain tags, and party level ranges. It is designed to work
* independently of encounter frequency calculations.
*
* Troop Note Tags (add to a troop's first event page comments):
* <region: x[, y, z, a-e]> - Specifies allowed region IDs.
* <terrain: w[, x-z]> - Specifies allowed terrain tags.
* <plevel: min-max> - Specifies the range of party levels required
* for the troop to appear.
*
* Example:
* <region: 1, 2, 5-8> - Troop appears in regions 1, 2, 5, 6, 7, 8.
* <terrain: 1-3> - Troop appears on terrain tags 1, 2, and 3.
* <plevel: 5-10> - Troop appears when the party level is between
* 5 and 10.
*
* Compatibility:
* - When using this plugin (808TroopCondition) with 808BattleFrequency,
* place this plugin **above** 808BattleFrequency in the plugin list.
* This ensures that troop filtering is applied after encounter frequency
* calculations.
* Permission: Free to use, do not repost, do not claim yours.
*/
(function() {
'use strict';
const PLUGIN_NAME = '808TroopCondition';
const parameters = PluginManager.parameters(PLUGIN_NAME);
const DEBUG_MODE = parameters['Debug'].toLowerCase() === 'true';
window.Imported = window.Imported || {};
window.Imported[PLUGIN_NAME] = true;
//=============================================================================
// * Constants and Utility Functions
//=============================================================================
const TAG_PATTERNS = {
REGION: /<region:s*([d,-s]+)>/i,
TERRAIN: /<terrain:s*([d,-s]+)>/i,
LEVEL: /<plevel:s*(d+)-(d+)>/i
};
class TroopConditionUtils {
static parseNumberRange(str) {
if (!str) return [];
const result = new Set();
const parts = str.split(',').map(p => p.trim());
for (const part of parts) {
if (part.includes('-')) {
const [start, end] = part.split('-').map(n => parseInt(n));
if (!isNaN(start) && !isNaN(end)) {
for (let i = Math.min(start, end); i <= Math.max(start, end); i++) {
result.add(i);
}
}
} else {
const num = parseInt(part);
if (!isNaN(num)) {
result.add(num);
}
}
}
return Array.from(result).sort((a, b) => a - b);
}
static getPartyAverageLevel() {
const members = $gameParty.battleMembers();
if (!members.length) return 1;
const total = members.reduce((sum, actor) => sum + actor.level, 0);
return Math.floor(total / members.length);
}
static getTroopConditions(troopId) {
const conditions = {
regions: [],
terrains: [],
levelRange: [0, 999],
hasConditions: false
};
const troop = $dataTroops[troopId];
if (!troop || !troop.pages || !troop.pages[0] || !troop.pages[0].list) return conditions;
const comments = troop.pages[0].list
.filter(cmd => cmd.code === 108 || cmd.code === 408)
.map(cmd => cmd.parameters[0]);
for (const comment of comments) {
// Region check
const regionMatch = comment.match(TAG_PATTERNS.REGION);
if (regionMatch) {
conditions.regions = this.parseNumberRange(regionMatch[1]);
conditions.hasConditions = true;
}
// Terrain check
const terrainMatch = comment.match(TAG_PATTERNS.TERRAIN);
if (terrainMatch) {
conditions.terrains = this.parseNumberRange(terrainMatch[1]);
conditions.hasConditions = true;
}
// Level check
const levelMatch = comment.match(TAG_PATTERNS.LEVEL);
if (levelMatch) {
const min = parseInt(levelMatch[1]);
const max = parseInt(levelMatch[2]);
if (!isNaN(min) && !isNaN(max)) {
conditions.levelRange = [Math.min(min, max), Math.max(min, max)];
conditions.hasConditions = true;
}
}
}
return conditions;
}
static getEligibleTroops(currentRegion, currentTerrain, partyLevel) {
const encounters = $gameMap.encounterList();
if (!encounters || encounters.length === 0) return null;
const eligibleTroops = [];
let totalWeight = 0;
// Check each encounter entry
for (const encounter of encounters) {
const troopId = encounter.troopId;
const weight = encounter.weight;
const conditions = this.getTroopConditions(troopId);
// Check if troop meets all conditions
const regionValid = conditions.regions.length === 0 ||
conditions.regions.includes(currentRegion);
const terrainValid = conditions.terrains.length === 0 ||
conditions.terrains.includes(currentTerrain);
const levelValid = partyLevel >= conditions.levelRange[0] &&
partyLevel <= conditions.levelRange[1];
if (regionValid && terrainValid && levelValid) {
eligibleTroops.push({ troopId, weight });
totalWeight += weight;
}
}
return { eligibleTroops, totalWeight };
}
static selectWeightedTroop(eligibleData) {
if (!eligibleData || eligibleData.eligibleTroops.length === 0) return 0;
const { eligibleTroops, totalWeight } = eligibleData;
let random = Math.random() * totalWeight;
for (const troop of eligibleTroops) {
random -= troop.weight;
if (random <= 0) {
return troop.troopId;
}
}
// Fallback to first eligible troop if something goes wrong
return eligibleTroops[0].troopId;
}
}
//=============================================================================
// * Troop Selection Override
//=============================================================================
const _Game_Player_makeEncounterTroopId = Game_Player.prototype.makeEncounterTroopId;
Game_Player.prototype.makeEncounterTroopId = function() {
const currentRegion = this.regionId();
const currentTerrain = $gameMap.terrainTag(this.x, this.y);
const partyLevel = TroopConditionUtils.getPartyAverageLevel();
// Get all eligible troops with their weights
const eligibleData = TroopConditionUtils.getEligibleTroops(
currentRegion,
currentTerrain,
partyLevel
);
// If no eligible troops found, return 0 to skip battle
if (!eligibleData || eligibleData.eligibleTroops.length === 0) {
if (DEBUG_MODE) {
console.log('No eligible troops found for current conditions:', {
region: currentRegion,
terrain: currentTerrain,
partyLevel: partyLevel
});
}
return 0;
}
// Select a troop based on weights from eligible troops
const selectedTroopId = TroopConditionUtils.selectWeightedTroop(eligibleData);
if (DEBUG_MODE) {
console.log('Selected troop from eligible pool:', {
selectedTroopId: selectedTroopId,
eligibleCount: eligibleData.eligibleTroops.length,
totalWeight: eligibleData.totalWeight
});
}
return selectedTroopId;
};
})(); |
A renommer 808BattleFrequency.js
Spoiler (cliquez pour afficher)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
| // File: 808BattleFrequency.js
/*:
* @plugindesc v1.2 Custom encounter frequency system for RPG Maker MV
* @version 1.2.0
* @author mugen808
*
* @param stepCheck
* @text Step Check Interval
* @desc Frequency of encounter checks (in steps).
* 0 = no checks, 1 = every step, 2 = every two steps, etc.
* @default 1
*
* @param Debug
* @type boolean
* @desc Set to true to enable console logs for debugging.
* @default false
*
* @help
* This plugin calculates encounter frequency based on a custom danger
* counter system and incorporates party level into encounter frequency.
*
* It allows for a more dynamic frequency of encounters based on party level
* relative to the area’s "danger level," or zone difficulty.
* This system does not affect troop selection or eligibility.
*
*==========================================================================
* Key Concepts:
* - **Danger Counter**: The danger counter increases with each step the
* player takes and resets after each battle. The higher this value,
* the higher the chance of a battle. The counter starts at 0, ensuring
* the first step after entering an area will not immediately trigger
* a battle. Each additional step raises the danger counter, gradually
* increasing the odds of an encounter.
*
* - **Zone Danger**: Zone danger reflects the difficulty of an area. The
* plugin uses the zone danger value relative to the party’s average
* level to influence encounter frequency.
* - A zone danger roughly equal to the party’s level results in a
* typical encounter frequency.
* - A zone danger much higher than the party’s level will lead to
* frequent encounters.
* - For instance, in a level 99 max system, a danger level of 99 produces
* normal encounter frequency for a level 99 party and high frequency for
* a level 25 party. A very high zone danger, such as 400, results in
* frequent encounters regardless of party level.
*
* **Party Level Adjustment**: The plugin’s main feature is to use party level
* to adjust encounter rates, so:
*
* - Low-level parties in high-level zones face frequent encounters.
* - High-level parties in low-level zones encounter fewer enemies.
* - Players in zones matching their party level experience standard encounter
* rates.
*
*==========================================================================
* Plugin Command:
* - `BattleFrequency reset`span style="color:#7cc4f5;"> : Resets the danger counter to 0.
* Note: This is automatically done once a battle completes or after leaving
* or entering a map.
*
*==========================================================================
* Map Notetag:
* - <zoneDanger x>: Sets a fixed zone danger value for the map.
* Example: <zoneDanger 18>
* - <zoneDanger region>: Uses the region ID as the zone danger value.
* Note:
* -If a zone danger value is not set in the map properties, the danger
* value will default to 0, preventing any encounters from being
* triggered on that map.
*
* - <stepCheck x>: Sets the step check interval for encounters (in steps).
* For example, <stepCheck 3> checks every 3 steps, while
* <stepCheck 1> checks every step.
* <stepCheck 1> means four times more encounter than <stepCheck 4>
* Notes:
* -The stepCheck interval value entered in a map note field will override
* the value set in the plugin parameter stepCheck. In other words, the
* parameter will only work in maps that do not have a stepCheck note
* tag.
*
* -This could be useful to lower or increase the encounter frequency
* in certain maps that need to have the same Zone Danger value.
* This is also useful if some maps use some sort of pixel movement
* while other maps use regular movement to ensure consistency between
* battle frequency.
* -Example: On the world map, we have MV's default movement system where
* one tile equals one step, while in dungeons, we use a pixel movement
* plugin where one tile equals three steps. In this case, set your
* stepCheck parameter to 3 and tag the world map with
* <stepCheck 1> for consistent encounter frequency across all maps.
*
*==========================================================================
* Compatibility:
* - When using this plugin (808BattleFrequency) alongside 808TroopCondition,
* place this plugin **beneath** 808TroopCondition in the plugin list.
* This order ensures that troop filtering conditions are applied before the
* encounter frequency calculations.
*
*--------------------------------------------------------------------------
*==========================================================================
* Encounter Formula Documentation:
*
*## Overview
* The encounter system uses a sophisticated formula that takes into account
* the party's level, the zone's danger level, and the accumulated danger
* counter to determine encounter chances. The system is designed to provide
* more nuanced encounter rates based on the difference between party level
* and zone difficulty.
*
*## Encounter Calculation Workflow
* - Each valid step adds 1024 to the danger counter.
* - Encounter checks occur based on the stepCheck interval.
* - At each check, a 0-255 random number is generated and compared to the
* calculated encounter chance. Battles will be triggered if that random
* number is inferior to the encounter chances.
* - The debug mode will display all calculation details for testing.
*
*## Core Formula Components
*
*### 1. Base Calculations
*
* levelDiff = zoneDanger - partyLevel
* absLevelDiff = |levelDiff| (absolute value)
*
*### 2. Weight Factor
*
* weightFactor = (absLevelDiff / 15 + 1)^1.5 - 1
*
* This creates a curve that:
* - Minimally impacts encounters when level differences are small
* - Moderately scales for medium level differences
* - Significantly impacts encounters for large level differences
*
*### 3. Direction Modifier
*
* direction = sign(levelDiff) // Returns 1 if zone is higher, -1 if party
* is higher. This simply affects the danger modifier based on whether the
* zone danger or party level is higher.
*
*### 4. Final Danger Modifier
*
* dangerModifier = clamp(1.0 + (direction * weightFactor * 0.25), 0.25, 4.0)
*
* Starting from a base value of 1.0 (100% normal rate), the formula adjusts
* the encounter rate based on level differences while maintaining reasonable
* bounds.
*
*### 5. Encounter Chance Calculation
*
* encounterChance = clamp(dangerCounter * dangerModifier / 256, 0, 256)
*
*## Example Outcomes
*
* 1. **Small Level Difference** (Level 3 party in level 2 zone):
* - levelDiff = -1
* - weightFactor ≈ 0.10
* - dangerModifier ≈ 0.97
* - Result: 97% of normal encounter rate
*
* 2. **Medium Level Difference** (Level 50 party in level 45 zone):
* - levelDiff = -5
* - weightFactor ≈ 0.25
* - dangerModifier ≈ 0.94
* - Result: 94% of normal encounter rate
*
* 3. **Large Level Difference** (Level 3 party in level 99 zone):
* - levelDiff = 96
* - weightFactor ≈ 19.13
* - dangerModifier = 4.0 (capped)
* - Result: 400% of normal encounter rate
*
* 4. **Extreme Level Difference** (Level 99 party in level 3 zone):
* - levelDiff = -96
* - weightFactor ≈ 19.13
* - dangerModifier = 0.25 (capped)
* - Result: 25% of normal encounter rate
*
*## Formula Characteristics
*
* - **Non-Linear Scaling**: The weight factor uses a power function
* (^1.5) to create non-linear scaling
* - **Small Difference Handling**: Level differences under 5 have
* minimal impact on encounter rates (less than 5% deviation)
* - **Large Difference Handling**: Level differences over 20 have
* exponentially increasing impact
* - **Capped Modifiers**: Final encounter rates are capped between
* 25% and 400% of the base rate
* - **Smooth Transition**: The formula provides smooth transitions
* between different level ranges
*#######################################################################
* Permission: Free to use, do not repost, do not claim yours.
*/
(function() {
'use strict';
const PLUGIN_NAME = '808BattleFrequency';
const parameters = PluginManager.parameters(PLUGIN_NAME);
let stepCheck = Number(parameters['stepCheck'] || 1);
const DEBUG_MODE = parameters['Debug'].toLowerCase() === 'true';
//=============================================================================
// * Utility Functions
//=============================================================================
function clamp(value, min, max) {
return Math.max(min, Math.min(max, value));
}
//=============================================================================
// * Game_Player modifications
//=============================================================================
const _Game_Player_initMembers = Game_Player.prototype.initMembers;
Game_Player.prototype.initMembers = function() {
_Game_Player_initMembers.call(this);
this.initBattleFrequencyMembers();
};
Game_Player.prototype.initBattleFrequencyMembers = function() {
this._dangerCounter = 0;
this._stepCounter = 0;
this._isInDangerZone = false;
};
Game_Player.prototype.resetDangerCounter = function() {
this._dangerCounter = 0;
this._stepCounter = 0;
};
// Gets the current zone danger from map notes
Game_Player.prototype.getCurrentZoneDanger = function() {
const note = $dataMap.note || '';
const match = note.match(/<zoneDangers+(d+|region)>/i);
if (!match) {
if (DEBUG_MODE) {
console.log('No zoneDanger tag found - plugin functionality paused');
}
this._isInDangerZone = false;
return null;
}
this._isInDangerZone = true;
if (match[1].toLowerCase() === 'region') {
return this.regionId();
}
return parseInt(match[1]);
};
// Party average level
Game_Player.prototype.getPartyAverageLevel = function() {
const members = $gameParty.battleMembers();
if (members.length === 0) return 1;
const totalLevels = members.reduce((sum, actor) => sum + actor.level, 0);
return Math.max(1, Math.floor(totalLevels / members.length));
};
// Step counting and encounter checks
const _Game_Player_increaseSteps = Game_Player.prototype.increaseSteps;
Game_Player.prototype.increaseSteps = function() {
_Game_Player_increaseSteps.call(this);
// Only process steps if in a danger zone
if (!this._isInDangerZone) return;
if (stepCheck <= 0) return;
this._stepCounter++;
if (this._stepCounter >= stepCheck) {
if (DEBUG_MODE) {
console.log(`nStep Count: ${this._stepCounter}, Danger Counter Before Increment: ${this._dangerCounter}`);
}
this.checkForBattleEncounter();
this._stepCounter = 0; // Reset step counter after check
this._dangerCounter = Math.min(this._dangerCounter + 1024, 262144); // danger counter increase +1024, cap 262144
if (DEBUG_MODE) {
console.log(`Danger Counter After Increment: ${this._dangerCounter}`);
}
}
};
Game_Player.prototype.checkForBattleEncounter = function() {
if (!this.canEncounter()) return;
const zoneDanger = this.getCurrentZoneDanger();
if (zoneDanger === null) return;
const partyLevel = this.getPartyAverageLevel();
const randomBattle = Math.floor(Math.random() * 256);
const levelDiff = zoneDanger - partyLevel;
const absLevelDiff = Math.abs(levelDiff);
const weightFactor = Math.pow(absLevelDiff / 15 + 1, 1.5) - 1;
const direction = Math.sign(levelDiff);
const dangerModifier = clamp(
1.0 + (direction * weightFactor * 0.25),
0.25, //minimum chances of encounter. 0.25 means 25% of normal chances. Will happen when party is high level in a low level zone.
4.0 //maximum chances of encounter. 4 means 400% of normal chances. Will happen when party is low level in a high level zone.
);
const encounterChance = clamp(this._dangerCounter * dangerModifier / 256, 0, 256);
const encounterPercentage = (encounterChance / 256) * 100; // For logging purpose only
if (DEBUG_MODE) {
console.log(`Zone Danger: ${zoneDanger}`);
console.log(`Party Average Level: ${partyLevel}`);
console.log(`Level Difference: ${levelDiff}`);
console.log(`Weight Factor: ${weightFactor}`);
console.log(`Final Danger Modifier: ${dangerModifier}`);
console.log(`Encounter Chance: ${encounterChance} / 256 (${encounterPercentage.toFixed(2)}%)`);
console.log(`Random Battle Roll: ${randomBattle}`);
}
if (randomBattle < encounterChance) {
this.initiateRandomEncounter();
}
};
// Checks if encounters are possible
Game_Player.prototype.canEncounter = function() {
return !$gameMap.isEventRunning() &&
$gameSystem.isEncounterEnabled() &&
!this.isInVehicle() &&
!this.isDebugThrough();
};
// Initiates the battle encounter
Game_Player.prototype.initiateRandomEncounter = function() {
this._dangerCounter = 0;
this._stepCounter = 0;
// Let the default system or other plugins handle troop selection
const troopId = this.makeEncounterTroopId();
if (DEBUG_MODE) {
console.log(`Selected Troop ID: ${troopId}`);
console.log(`Danger Counter Reset to: ${this._dangerCounter}`);
}
if (troopId > 0) {
BattleManager.setup(troopId, true, false);
BattleManager.onEncounter();
SceneManager.push(Scene_Battle);
} else {
if (DEBUG_MODE) {
console.log(`No valid troop found for encounter. Encounter skipped.`);
}
// Space left for handling cases when a battle is triggered but no troops qualify for the encounter.
// If this section is left empty, the battle will simply be skipped. Else, add the logic here.
}
};
const _BattleManager_endBattle = BattleManager.endBattle;
BattleManager.endBattle = function(result) {
_BattleManager_endBattle.call(this, result);
$gamePlayer.resetDangerCounter(); // Ensures danger counter resets to 0 after battle
};
//=============================================================================
// * Map Setup
//=============================================================================
Game_Map.prototype.getStepCheckValue = function() {
const note = $dataMap.note || '';
const match = note.match(/<stepChecks+(d+)>/i);
if (match) {
return Number(match[1]);
}
return stepCheck; // Fallback to default parameter
};
const _Game_Map_setup = Game_Map.prototype.setup;
Game_Map.prototype.setup = function(mapId) {
_Game_Map_setup.call(this, mapId);
stepCheck = this.getStepCheckValue();
$gamePlayer.resetDangerCounter();
// Force check of zone danger status on map load
$gamePlayer.getCurrentZoneDanger();
};
//=============================================================================
// * Plugin Commands
//=============================================================================
const _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
_Game_Interpreter_pluginCommand.call(this, command, args);
if (command.toLowerCase() === 'battlefrequency') {
if (args[0].toLowerCase() === 'reset') {
$gamePlayer.resetDangerCounter();
}
}
};
//=============================================================================
// * Disable Original Encounter System
//=============================================================================
Game_Player.prototype.makeEncounterCount = function() {
this._encounterCount = Infinity; //Disable MV frequency calculation so that this plugin does not generate battles in addition to MV default encounter system, but rather instead of it.
};
})(); |
A nommer 808BattleTransition.js
Spoiler (cliquez pour afficher)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
| // File: 808BattleTransition.js
/*:
* @plugindesc Seamless Shatter Effect Battle Transition
* @author mugen808
*
* @help
* This plugin creates a shatter transition between map and battle scenes.
* The screen breaks into fragments that reveal the battle scene underneath
* when entering combat.
*
* **Compatibility**:
* - This plugin should be placed **below** the 808BattleFrequency and
* 808TroopCondition plugins in the plugin list.
* Permission: Free to use, do not repost, do not claim yours.
*/
(function() {
let transitionContainer = null;
class ShatterTransitionContainer extends PIXI.Container {
constructor() {
super();
this.fragments = [];
this.isActive = false;
this.battleSceneReady = false;
}
initialize(mapScene, battleScene) {
this.mapSnapshot = Bitmap.snap(mapScene);
this.battleScene = battleScene;
this.fragmentSize = 32;
this.createFragments();
this.isActive = true;
this.battleSceneReady = false;
}
createFragments() {
const width = Graphics.width;
const height = Graphics.height;
const columns = Math.ceil(width / this.fragmentSize);
const rows = Math.ceil(height / this.fragmentSize);
for (let row = 0; row < rows; row++) {
for (let col = 0; col < columns; col++) {
const x = col * this.fragmentSize;
const y = row * this.fragmentSize;
const fragment = new Sprite(this.mapSnapshot);
fragment.setFrame(x, y, this.fragmentSize, this.fragmentSize);
fragment.x = x + this.fragmentSize / 2;
fragment.y = y + this.fragmentSize / 2;
fragment.anchor.x = 0.5;
fragment.anchor.y = 0.5;
fragment.velocity = {
x: (Math.random() * 4) - 2,
y: -Math.random() * 6 - 2
};
fragment.rotationSpeed = (Math.random() * 0.1) - 0.05;
fragment.delay = Math.floor(Math.random() * 15);
fragment.fadeSpeed = Math.random() * 0.015 + 0.01;
fragment.scale.x = 1;
fragment.scale.y = 1;
// Add minimum lifespan to ensure visibility
fragment.minLifespan = 60 + Math.floor(Math.random() * 30); // 1~1.5 seconds at 60fps
fragment.lifetime = 0;
this.fragments.push(fragment);
this.addChild(fragment);
}
}
}
update() {
if (!this.isActive) return;
for (let i = this.fragments.length - 1; i >= 0; i--) {
const fragment = this.fragments[i];
if (fragment.delay > 0) {
fragment.delay--;
continue;
}
fragment.lifetime++;
fragment.x += fragment.velocity.x;
fragment.y += fragment.velocity.y;
fragment.velocity.y += 0.2;
fragment.rotation += fragment.rotationSpeed;
if (fragment.lifetime > fragment.minLifespan) {
fragment.opacity -= fragment.fadeSpeed * 255;
}
fragment.scale.x *= 0.99;
fragment.scale.y *= 0.99;
if (fragment.opacity <= 0 && fragment.lifetime > fragment.minLifespan) {
this.removeChild(fragment);
this.fragments.splice(i, 1);
if (this.fragments.length === 0) {
this.isActive = false;
if (this.parent) {
this.parent.removeChild(this);
}
transitionContainer = null;
break;
}
}
}
}
}
const _Scene_Map_startEncounterEffect = Scene_Map.prototype.startEncounterEffect;
Scene_Map.prototype.startEncounterEffect = function() {
_Scene_Map_startEncounterEffect.call(this);
transitionContainer = new ShatterTransitionContainer();
transitionContainer.initialize(this, SceneManager.nextScene);
this.addChild(transitionContainer);
};
const _Scene_Map_updateEncounterEffect = Scene_Map.prototype.updateEncounterEffect;
Scene_Map.prototype.updateEncounterEffect = function() {
_Scene_Map_updateEncounterEffect.call(this);
if (transitionContainer) {
transitionContainer.update();
}
};
const _Scene_Battle_create = Scene_Battle.prototype.create;
Scene_Battle.prototype.create = function() {
_Scene_Battle_create.call(this);
if (transitionContainer) {
this.addChild(transitionContainer);
}
};
const _Scene_Battle_update = Scene_Battle.prototype.update;
Scene_Battle.prototype.update = function() {
_Scene_Battle_update.call(this);
if (transitionContainer) {
transitionContainer.update();
}
};
})(); |
|
Posté dans Forum - [MV] 808PrintScreen |
mugen808 -
posté le 07/09/2024 à 15:28:49. (6 messages postés) |
| Plugin simple et léger pour MV permettant de prendre des captures d'écran en jeu. Il s'agit d'un screenshot classique où tout ce qui est affiché à l'écran sera capturé dans l'image. Différent d'OrangeMapShot qui ne sauvegarde que la carte.
Attribuez la touche de capture d'écran souhaitée dans les paramètres et décidez si vous souhaitez voir une notification à l'écran lorsque la capture est enregistrée.
Les images seront enregistrées dans le dossier 'screenshots' à la racine du répertoire du jeu. Le dossier sera créé automatiquement.
Par défaut, le plugin cesse de fonctionner et affiche un avertissement lorsqu'il y a 999 images dans le dossier 'screenshots'.
Nom du fichier : 808PrintScreen.js
Code:
Spoiler (cliquez pour afficher)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
| //==============================================================================
// 808PrintScreen
//==============================================================================
// File: 808PrintScreen.js
// v1.0
// 7th Sep 2024
//==============================================================================
/*:
* @plugindesc v1.0 Allows taking screenshots by pressing a specified key and saving them to the 'screenshots' folder. Optionally displays a notification on screen.
* @author mugen808
* @param Screenshot Key
* @desc The key to press for taking a screenshot. Default: F7
* @default F7
* @param Screenshot Notification
* @type boolean
* @desc Whether to display a screenshot notification on screen. Default: true
* @default true
* @help
*==============================================================================
* 808PrintScreen
*==============================================================================
*
* This plugin enables taking screenshots of the game by pressing a specified
* key. Screenshots are saved in a 'screenshots' folder in the game directory.
*
* -Available keys:
* F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, A, B, C, D, E, F, G, H,
* I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6,
* 7, 8, 9, Shift, Ctrl, Alt, Space, Enter, Escape, Left, Up, Right, Down,
* PrintScreen.
*
*
* By default, a notification will be displayed on the screen when a screenshot
* is taken. This can be deactivate in the plugin parameters.
*
* The screenshot will still be logged in the console regardless of the
* notification setting.
*
* -Parameters:
* Screenshot Key: The key to press for taking a screenshot (default: F7).
*
* Screenshot Notification: Whether to display a notification on the screen
* (default: true).
*
*
*==============================================================================
* Terms
*==============================================================================
*
* Free to use. Redistribution not permitted.
*
*..............................................................................
*/
(function() {
const fs = require('fs');
const path = require('path');
const parameters = PluginManager.parameters('808PrintScreen');
const screenshotKey = parameters['Screenshot Key'] || 'F7';
const screenshotNotification = String(parameters['Screenshot Notification'] || 'false').toLowerCase() === 'true';
function getKeyCode(keyName) {
const keyCodes = {
'F1'span style="color:#7cc4f5;"> : 112, 'F2'span style="color:#7cc4f5;"> : 113, 'F3'span style="color:#7cc4f5;"> : 114, 'F4'span style="color:#7cc4f5;"> : 115, 'F5'span style="color:#7cc4f5;"> : 116, 'F6'span style="color:#7cc4f5;"> : 117, 'F7'span style="color:#7cc4f5;"> : 118, 'F8'span style="color:#7cc4f5;"> : 119, 'F9'span style="color:#7cc4f5;"> : 120, 'F10'span style="color:#7cc4f5;"> : 121, 'F11'span style="color:#7cc4f5;"> : 122, 'F12'span style="color:#7cc4f5;"> : 123,
'A'span style="color:#7cc4f5;"> : 65, 'B'span style="color:#7cc4f5;"> : 66, 'C'span style="color:#7cc4f5;"> : 67, 'D'span style="color:#7cc4f5;"> : 68, 'E'span style="color:#7cc4f5;"> : 69, 'F'span style="color:#7cc4f5;"> : 70, 'G'span style="color:#7cc4f5;"> : 71, 'H'span style="color:#7cc4f5;"> : 72, 'I'span style="color:#7cc4f5;"> : 73, 'J'span style="color:#7cc4f5;"> : 74, 'K'span style="color:#7cc4f5;"> : 75, 'L'span style="color:#7cc4f5;"> : 76, 'M'span style="color:#7cc4f5;"> : 77, 'N'span style="color:#7cc4f5;"> : 78, 'O'span style="color:#7cc4f5;"> : 79, 'P'span style="color:#7cc4f5;"> : 80, 'Q'span style="color:#7cc4f5;"> : 81, 'R'span style="color:#7cc4f5;"> : 82, 'S'span style="color:#7cc4f5;"> : 83, 'T'span style="color:#7cc4f5;"> : 84, 'U'span style="color:#7cc4f5;"> : 85, 'V'span style="color:#7cc4f5;"> : 86, 'W'span style="color:#7cc4f5;"> : 87, 'X'span style="color:#7cc4f5;"> : 88, 'Y'span style="color:#7cc4f5;"> : 89, 'Z'span style="color:#7cc4f5;"> : 90,
'0'span style="color:#7cc4f5;"> : 48, '1'span style="color:#7cc4f5;"> : 49, '2'span style="color:#7cc4f5;"> : 50, '3'span style="color:#7cc4f5;"> : 51, '4'span style="color:#7cc4f5;"> : 52, '5'span style="color:#7cc4f5;"> : 53, '6'span style="color:#7cc4f5;"> : 54, '7'span style="color:#7cc4f5;"> : 55, '8'span style="color:#7cc4f5;"> : 56, '9'span style="color:#7cc4f5;"> : 57,
'Shift'span style="color:#7cc4f5;"> : 16, 'Ctrl'span style="color:#7cc4f5;"> : 17, 'Alt'span style="color:#7cc4f5;"> : 18, 'Space'span style="color:#7cc4f5;"> : 32, 'Enter'span style="color:#7cc4f5;"> : 13, 'Escape'span style="color:#7cc4f5;"> : 27, 'Left'span style="color:#7cc4f5;"> : 37, 'Up'span style="color:#7cc4f5;"> : 38, 'Right'span style="color:#7cc4f5;"> : 39, 'Down'span style="color:#7cc4f5;"> : 40,
'PrintScreen'span style="color:#7cc4f5;"> : 44
};
return keyCodes[keyName] || null;
}
const keyCode = getKeyCode(screenshotKey);
if (keyCode === null) {
throw new Error(`Invalid key: ${screenshotKey}`);
}
Input.keyMapper[keyCode] = 'screenshot';
let screenshotQueue = [];
let screenshotTimeout = null;
function getNextFileName(dirPath) {
for (let i = 1; i <= 999; i++) { // limit of screenshot files in the folder
const fileName = `img${String(i).padStart(3, '0')}.png`;
const filePath = path.join(dirPath, fileName);
if (!fs.existsSync(filePath)) {
return fileName;
}
}
return null; // No available file names
}
function takeScreenshot() {
const dirPath = path.join(process.cwd(), 'screenshots');
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath);
}
const fileName = getNextFileName(dirPath);
if (!fileName) {
console.error('Screenshot limit reached. Please delete some screenshots and try again.');
if (screenshotNotification) {
displayScreenshotText('Screenshot limit reached. Please delete some screenshots and try again.');
}
return;
}
const filePath = path.join(dirPath, fileName);
const bitmap = Graphics._canvas.toDataURL('image/png').replace(/^data:image\/png;base64,/, "");
fs.writeFile(filePath, bitmap, 'base64', function(err) {
if (err) {
console.error('Failed to save screenshot:', err);
} else {
console.log('Screenshot saved as', fileName);
if (screenshotNotification) {
displayScreenshotText(fileName);
}
}
});
}
function displayScreenshotText(message) {
const text = new PIXI.Text(`Screenshot ${message}`, { fontFamily: 'Arial', fontSize: 12, fill: 'white' });
text.x = Graphics.width - text.width - 10;
text.y = 10 + screenshotQueue.length * 20;
SceneManager._scene.addChild(text);
screenshotQueue.push(text);
setTimeout(() => {
SceneManager._scene.removeChild(text);
screenshotQueue.shift();
updateScreenshotQueue();
}, 2150);
}
function updateScreenshotQueue() {
screenshotQueue.forEach((text, index) => {
text.y = 10 + index * 20;
});
}
const alias_SceneManager_update = SceneManager.update;
SceneManager.update = function() {
alias_SceneManager_update.call(this);
if (Input.isTriggered('screenshot')) {
if (!screenshotTimeout) {
takeScreenshot();
screenshotTimeout = setTimeout(() => {
screenshotTimeout = null;
}, 200);
}
}
};
})();
|

|
Posté dans Forum - [MV] (SWR) Simple Water Reflection (basé sur les Region ID) |
mugen808 -
posté le 07/09/2024 à 10:41:36. (6 messages postés) |
| Merci les gars! Petit update de la version 0.6b vers la 0.7b.
Rien de bien signifiant, c'est toujours le meme plugin.
J'ai juste converti les déclarations de variables en let et const au lieu de var utilisé précedemment.
Je bosse sur un gros truc la, un plugin pour afficher et animer du texte a l'ecran, principal but remplacer la méhode par défaut pour afficher le nom des maps.
Mais bon, c'est du texte qui s'affiche, ca peut servir à d'autres trucs aussi.
|
Posté dans Forum - [MV] (SWR) Simple Water Reflection (basé sur les Region ID) |
mugen808 -
posté le 31/08/2024 à 10:11:39. (6 messages postés) |
| EDIT:
Code ci dessous mis a jour en 0.9
Si vous telechargez la demo, copiez ce code et remplacez celui du plugin de la demo avec.
Pour les deux fichiers 808_SWR_SimpelWaterReflect.js et 808_SWR_LayerZ.js.
-------------------------------------------------------------------------------------------------------------------
Bonjour!
Je me suis fait un petit script (SWR) pour mes besoins perso et je me suis dit que ça pourrait peut-être profiter à quelqu’un, alors je le partage!
J’ai fait la démo et le plugin en anglais et j’avoue la flemme de tout traduire. Mais je vais laisser les instructions complètes en français sur ce post^^.
Mon RPG Maker est en anglais, donc il se peut que ma traduction soit parfois approximative, je ne connais pas le nom des fonctions en français.
Je détaille ici la description en français. Il y a aussi un lien vers la démo à
la fin du post.
Simple Water Reflection
Plugin pour RPG Maker MV 1.6
Nom du fichier : SimpleWaterReflect.js
________________________________________
Description
Ajoute des reflets (du héro ou des évènements) au-dessus de la couche de parallax en utilisant les régions (Region ID). Effets configurables, tels que le décalage de la distance du reflet (offset), réflexion directionnelle, options d’échelle des longueur/ largeur des reflets, et d’autres.
Ce plugin affiche uniquement un reflet au sol, il n’y a pas de fonction miroir (pour les murs)
Instructions:
Spoiler (cliquez pour afficher)
Paramètres (Spoiler dans le spoiler)
Spoiler (cliquez pour afficher) • Régions de Réflexion
IDs des régions où les reflets doivent apparaître. Entrez-les sous forme de valeurs séparées par des virgules (par ex. 1,7,9).
Par défaut : 10
• Opacité de Réflexion
Opacité du reflet (0-255).
Par défaut : 128
• Échelle de Réflexion
Échelle verticale + horizontale du reflet (0.1-2).
Par défaut : 1
• Échelle Horizontale de Réflexion (largeur)
Échelle horizontale du reflet (0.1-2).
Par défaut : 1.05
• Échelle Verticale de Réflexion (longueur)
Échelle verticale du reflet (0.1-2).
Par défaut : 0.85
• Réflexion du Héros
Refléter le personnage joueur (héros) ?
Par défaut : true
• Réflexion des Followers
Refléter les followers ?
Par défaut : true
• Réflexion des Événements
Refléter les événements de la carte ?
Par défaut : true
• Amplitude des Ondulations
Amplitude de l'effet d'ondulation (0.0 à 10.0).
Par défaut : 2
• Fréquence des Ondulations
Fréquence de l'effet d'ondulation (0.1 à 10.0).
Par défaut : 3
• Amplitude de la Distorsion
Amplitude de l'effet de distorsion (0.0 à 10.0) (expérimental).
Par défaut : 0
• Fréquence de la Distorsion
Fréquence de l'effet de distorsion (0.1 à 10.0) (expérimental).
Par défaut : 0
• Amplitude du Ripple (vague)
Amplitude de l'effet de ripple (0.0 à 10.0) (expérimental).
Par défaut : 0
• Fréquence du Ripple (vague)
Fréquence de l'effet de ripple (0.1 à 10.0) (expérimental).
Par défaut : 0
• Décalage de Réflexion (Offset)
Décalage du sprite du reflet. Les valeurs négatives sont acceptées. Ex : -10
Par défaut : 0
• Angle de Réflexion
Angle de la réflexion en degrés (-180 à 180).
Par défaut : 5
• Niveau Vertical des Reflets
Niveau du Z-index de la réflexion dans la couche de parallax (les valeurs plus basses sont affichées en dessous).
Par défaut : 6
• Réflexion Directionnelle
La réflexion doit-elle suivre la direction du personnage ?
Par défaut : false
• Largeur du Personnage
Largeur du personnage en pixels (par défaut 48).
Par défaut : 48
• Hauteur du Personnage
Hauteur du personnage en pixels (par défaut 48).
Par défaut : 48 Fin du spoiler dans le spoiler.
Instructions d'Utilisation
Prérequis Graphiques et Cartographiques :
• Les reflets apparaissent dans les régions spécifiées dans les paramètres du plugin.
Les régions se trouvent à gauche sur le panneau des tilesets, dans l’onglet R après A B C D E. Ce ne sont pas les Terrain Tag ID.
• Il vaut mieux étendre l'ID de région de réflexion autour de la zone de réflexion pour éviter tout retard d'apparition du reflet. (Voir la démo)
• Le niveau Z des parallax se trouve en dessous du niveau du sol, donc les reflets n'apparaîtront pas sur l'herbe par défaut, même avec la bonne région ID.
• Les tiles ou autotiles d'eau doivent être semi-transparents pour permettre l'apparition du reflet. En utilisant des tiles semi transparents pour le sol, leur couleur sera obscurice par le jeu en l'absence de parallax. Vous pouvez utiliser des graphismes semi-transparents pour le sol et preserver leur luminosité en ajoutant un parallax a la zone. Ce faisant, les reflets apparaitront sous le sol (transparent) mais au dessus des parallax.
Dans ce scénario, le parallax peut avoir un motif comme pour simuler de la glace ou un fond marin.
• Pour simuler un reflet sur une surface non liquide, comme du verre, utilisez des tiles semi-transparents pour le sol.
• Les parallax peuvent être utilisés à la place des tiles/autotiles d'eau, et les reflets apparaîtront au-dessus du parallax. (Par exemple sur la seconde caputre ecran de ce post, l'eau est faite avec un parallax mis en mouvement par un autre plugin, Galv Layer Graphic )
________________________________________
Fonctionnalités & Paramètres
• Vous pouvez ajouter un effet d'ondulation dans les paramètres pour simuler le mouvement de l'eau.
• Les paramètres du plugin permettent de définir des règles générales pour les reflets des événements.
• La Réflexion Directionnelle corrélera la direction des reflets à la direction de leur personnage, alors que le comportement par défaut est fixe vers le sud. (Avec un angle à 0°).
• Le paramètre Largeur et Hauteur du Personnage est utile si vous utilisez la Réflexion Directionnelle avec des sprites dont la taille est différente de celle de base (48*48).
________________________________________
Tags & Commentaires
• Pour contrôler les reflets des événements individuellement, utilisez les tags :
<reflect_on>
<reflect_off>
• Les tags dans le champ Note d'un événement écraseront les paramètres du plugin pour cet événement.
• Les tags dans le champ Commentaire (page active de l’évènement uniquement) mettront le reflet à jour dynamiquement.
• Les tag en commentaire prendront le dessus sur ceux dans le champ Note si les deux sont présents simultanément.
________________________________________
Commandes de Plugin
• Les commandes de plugin permettent de contrôler divers effets en jeu :
o SetReflectionAngle [angle] - Définit l'angle de la réflexion.
o Ex : SetReflectionAngle 30
o SetReflectionOffset [offset] - Définit le décalage de la réflexion.
o SetReflectionLayer [layer] - Définit la couche Z-index pour la réflexion.
o SetDirectionalReflection [true/false] - Active ou désactive la réflexion directionnelle.
o SetReflectOpacity [opacity] - Définit l'opacité de la réflexion.
o SetReflect_XScale [scale] - Définit l'échelle horizontale de la réflexion.
o SetReflect_YScale [scale] - Définit l'échelle verticale de la réflexion.
o SetWaveEffect [true/false] - Active ou désactive l'effet d'ondulation.
o Ex : SetWaveEffect false
o SetRippleEffect [true/false] - Active ou désactive l'effet de ripple.
o SetDistortionEffect [true/false] - Active ou désactive l'effet de distorsion.
SCRIPT CALL:
Des script call (appels de script) sont disponibles pour stocker la valeur de la réflexion directionnelle et du décalage de la réflexion.
Stocker les valeurs
ReflectionOffset (valeur) : Stocker la valeur dans la variable x : $gameVariables.setValue(x, window.getReflectionOffset());
Exemple pour utiliser la variable 2 comme conteneur : $gameVariables.setValue(2, window.getReflectionOffset());
DirectionalReflection (0 ou true) : Stocker la valeur dans la variable y : $gameVariables.setValue(y, window.getDirectionalReflection());
Restaurer les valeurs à partir de la variable :
Reflection Offset : var value = $gameVariables.value(x); window.setReflectionOffset(value);
DirectionalReflection : var value = $gameVariables.value(y); window.setDirectionalReflection(value);
________________________________________
Compatibilité
• Testé uniquement avec les parallax d’origine : Je n'ai pas rencontré de problèmes de compatibilité, mais théoriquement, cela pourrait fonctionner différemment avec des plugins qui modifient la manière dont les parallax sont gérés par le moteur du jeu.
• Galv's Layer Graphics :
• Le parallax du plugin de Galv apparaîtra au-dessus du reflet de Simple Water Reflection, empêchant ce dernier d'apparaître si les calques de Galv ne sont pas semi transparents.
• Cependant, il existe un patch séparé (Plugin: SWR_LayerZ.js inclus) pour permettre aux reflets de ce plugin d'apparaître au-dessus des parallax de Galv's Layer Graphics.
• SWR devrait normalement être compatible nativement avec des sprites de tailles différentes (même différents de la taille par défaut de 48*48) ou avec des plugins qui modifient le nombre d'animations.
• Si vous utilisez des personnages de tailles différentes, les options de largeur /hauteur dans les paramètres du plugin ne devrait pas être nécessaires, sauf si vous utilisez la réflexion directionnelle.
• Si vous utilisez un plugin qui modifie le nombre d’animations, SWR doit être placé avant (au-dessus).
________________________________________
Problèmes Connus
• Il se peut que vous rencontriez un crash avec le message d'erreur : "cannot read property 'pivot' of null" dans certaines circonstances spécifiques.
• Bien que cela soit rare, ce problème survient généralement lorsque vous modifiez le statut de réflexion d'un événement tout en changeant simultanément son apparence graphique — que ce soit en jouant une animation sur l'événement ou en changeant son apparence en passant d'une page à l'autre — juste avant que l'événement ne bascule vers une nouvelle page où le statut de réflexion change (par exemple, une page affiche la réflexion et l'autre non).
• Si ce problème se produit, il vous suffit d'ajouter un wait (de 6 à 90 frames) avant de passer à la nouvelle page de l'événement. Il y a un exemple concret dans la démo avec la réflexion du tronc d’arbre sur la glace.
________________________________________
Conditions
• Libre d'utilisation
• Ne pas reposter
• Je n'ai aucune relation avec Galv et son plugin Layer Graphics est disponible sur son site https://galvs-scripts.com/2015/10/30/mv-layer-graphics/
808_SWR_SimpleWaterReflect.js
Spoiler (cliquez pour afficher)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
| //===============================================================================
// Simple Water Reflection
//===============================================================================
// RPG Maker MV Plugin
// File: 808_SWR_SimpleWaterReflect.js
//...............................................................................
// Version: Beta 0.9
// Date: 18 Aug. 2024
//...............................................................................
//===============================================================================
/*:
* @plugindesc v0.9b - Adds character reflections above the parallax layer using region tags.
* Configurable effects, offset, directional reflect, and size options.
* @author mugen808
*
* @param Reflect Regions
* @type text
* @desc Region IDs where reflections should appear. Enter as comma-separated values (e.g., 1,7,9).
* @default 10
*
* @param Reflect Opacity
* @type number
* @desc Opacity of the reflection (0-255).
* @default 128
*
* @param Reflect Scale
* @type number
* @desc Vertical scale of the reflection (0.1-2).
* @default 1
*
* @param Reflect Horizontal Scale
* @type number
* @desc Horizontal scale of the reflection (0.1-2).
* @default 1.05
*
* @param Reflect Vertical Scale
* @type number
* @desc Vertical scale of the reflection (0.1-2).
* @default 0.85
*
* @param Reflect Hero
* @type boolean
* @desc Reflect the player (hero) character?
* @default true
*
* @param Reflect Followers
* @type boolean
* @desc Reflect follower characters?
* @default true
*
* @param Reflect Events
* @type boolean
* @desc Reflect map events?
* @default true
*
* @param Wave Amplitude
* @type number
* @desc Amplitude of the wave effect (0.0 to 10.0).
* @default 2
*
* @param Wave Frequency
* @type number
* @desc Frequency of the wave effect (0.1 to 10.0).
* @default 3
*
* @param Distortion Amplitude
* @type number
* @desc Experimental. Amplitude of the distortion effect (0.0 to 10.0).
* @default 0
*
* @param Distortion Frequency
* @type number
* @desc Experimental. Frequency of the distortion effect (0.1 to 10.0).
* @default 0
*
* @param Ripple Amplitude
* @type number
* @desc Experimental. Amplitude of the ripple effect (0.0 to 10.0).
* @default 0
*
* @param Ripple Frequency
* @type number
* @desc Experimental. Frequency of the ripple effect (0.1 to 10.0).
* @default 0
*
* @param Reflection Offset
* @type number
* @desc Offset for the reflection sprite. Can input negative values. Ex: -10
* @default 0
*
* @param Reflection Angle
* @type number
* @desc Angle of reflection in degrees. (-180 to 180)
* @default 5
*
* @param Reflection Layer
* @type number
* @desc Z-index layer of the reflection in the parallax layer (lower values are drawn underneath).
* @default -1
*
* @param Directional Reflection
* @type boolean
* @desc Should the reflection face the direction of the character?
* @default false
*
* @help
* Simple Water Reflection
*==============================================================================
* This plugin adds character reflections on the parallax level based on
* region tags.
*
*
*------------------------------------------------------------------------------
* HOW TO USE
*------------------------------------------------------------------------------
* Graphic And Mapping Requirements:
*
* - Reflections appear in the regions specified in the plugin parameters.
* (Regions are on the left panel of RPG Maker after layers A, B, C, D, E;
* it is the R tab, they are not Terrain Tags).
*
* - It is best to tag the tiles around the reflection area with the reflection
* Region ID to ensure there is no delay with the appearance of the reflection
* once the hero arrives on water. See the demo for a showcase.
*
* - Parallax level is under the ground level, so default grass (even with the
* correct region ID) won't let the character's reflection appear.
*
* - The water tileset or autotiles require to be semi-transparent to let the
* reflection appear.
*
* - To simulate a reflection on non-liquid surface, glass for instance, the
* floor tileset used for ground has to be semi-transparent. A glass pattern
* or blue color parallax may possibly be used under the ground tiles to avoid
* darkening the mid-opacity floor tiles with no parallax under them.
*
* - Parallaxes can be used instead of water tiles/autotiles and the reflections
* will appear above the parallax and under the ground.
*
*
*------------------------------------------------------------------------------
* FEATURES & PARAMETERS
*------------------------------------------------------------------------------
*
* - You can add a wave effect in the plugin parameters to simulate water
* undulation.
*
* - The plugin parameters allow setting general rules for events' reflection,
* determining if they should normally be displayed.
*
* - Directional Reflection will have the reflection follow the hero's direction,
* while default behavior when Reflection Angle = 0 is fixed to south.
*
*
*------------------------------------------------------------------------------
* NOTES & COMMENT TAGS
*------------------------------------------------------------------------------
*
* - If you want to control which events may reflect or not individually, use
* the following tags:
*
* <reflect_on>
* <reflect_off>
*
* Note Field:
* - If one of these tags is stored in the NOTE field of an event, this
* instruction will override the plugin parameters.
* - Example: If your plugin parameter is set to reflect events, but Event 010
* has the <reflect_off> tag in its Note field, Event 010 will not display a
* reflection.
*
* Comment Field (Active Page Only):
* - These tags can also be used in a COMMENT to dynamically update whether an
* event should reflect or not.
* - When using the tags in a comment rather than in a note field, the tag
* will override the plugin parameters only IF the comment is on the active
* page of the event.
*
* Comment Overrides Note:
* - If contradictory tags are present in both the event's Note and the
* event's active page Comment field simultaneously, the Comment will take
* precedence, allowing you to set a general reflection rule for this event
* (without repeating it on every page, thanks to the Note), and create an
* exception on the active page (thanks to the Comment), if needed.
*
* Tag conflict:
* - <reflect_on> and <reflect_off> should obviously not been put together in
* the same Note field. If you need both effects on the same event, rather
* use comments on its relevant pages. Should both Note tags be present in
* the same event's note field and the <reflect_off> tag will take precedence.
*
*
*------------------------------------------------------------------------------
* PLUGIN COMMANDS
*------------------------------------------------------------------------------
*
* Different effects can be invoked in the game with plugin commands:
*
* - SetReflectionAngle [angle] - Sets the angle of the reflection.
* Example: SetReflectionAngle -30
*
* - SetReflectionOffset [offset] - Sets the reflection offset for the reflection
* sprite.
* Example: SetReflectionOffset 40
*
* - SetReflectionLayer [layer] - Sets the Z-index layer for the reflection
* in the parallax layer.
* Example: SetReflectionLayer 10
*
*
* - SetDirectionalReflection [true/false] - Enable or disable directional
* reflection.
* Example: SetDirectionalReflection true
*
*
* - SetReflectOpacity [opacity] - Sets the opacity of the reflection. (0 ~ 255 )
* Example: SetReflectOpacity 128
*
* - SetReflect_XScale [scale] - Sets the horizontal scale of the reflection
* based on the character sprite size
* Example: SetReflect_XScale 1.15 //(original size +15%)
*
* - SetReflect_YScale [scale] - Sets the vertical scale of the reflection
* based on the character sprite size
* Example: SetReflect_YScale 0.78 //(Original size -22%)
*
* - Effects deactivation
* Those commands may come in a handy before entering a non-liquid reflective
* surfaces:
*
* - SetWaveEffect [true/false] - Enable or disable the wave effect.
* Example: SetWaveEffect false
*
*
* - SetRippleEffect [true/false] - Enable or disable the ripple effect.
* Example: SetRippleEffect true
*
*
* - SetDistortionEffect [true/false] - Enable or disable the distortion effect.
* Example: SetDistortionEffect true
*
*
*------------------------------------------------------------------------------
* SCRIPT CALL
*------------------------------------------------------------------------------
*
* Script calls to store the value of Directional Reflection and Reflection
* offset are available.
*
* - Storing values
*
* - ReflectionOffset (value) :
* Storing the value in variable x:
* $gameVariables.setValue(x, window.getReflectionOffset());
*
* Example to use Variable 2 as container:
* $gameVariables.setValue(2, window.getReflectionOffset());
*
* - DirectionalReflection (0 or true) :
* Storing the value in variable y:
* $gameVariables.setValue(y, window.getDirectionalReflection());
*
*
* - Restoring values from variable:
*
* - Reflection Offset:
* var value = $gameVariables.value(x);
* window.setReflectionOffset(value);
*
* - DirectionalReflection:
* var value = $gameVariables.value(y);
* window.setDirectionalReflection(value);
*
*
*------------------------------------------------------------------------------
* COMPATIBILITY
*------------------------------------------------------------------------------
*
* - Tested with Default Parallaxes Only:
* I haven't encountered compatibility issues, but theoretically, this may work
* differently with plugins that modify the way parallaxes are handled by the
* game engine.
*
* - Galv's Layer Graphics:
* - Parallax from Galv's plugin will appear above the reflection from Simple
* Water Reflection, preventing it from appearing if Galv's layers aren't
* set to mid opacity.
* - There is however a separate plugin patch (SWR_LayerZ.js) to allow
* the reflections of this plugin to display above Galv's parallax with Galv
* 's Layer Graphics.
*
* -Animation Frames :
* This will work perfectly with default 3 frames sprites. If you have a
* number of frames different than 3, the directional reflection might have
* issues. Unless you are using Galv_CharacterFrames: Galv method has been
* included in this plugin, eg spritesheets names ending by %(x), where x is
* an integer and the sprite has x animations.
* Ex hero%(4).png
* If the suffix is missing, the plugin will consider it is a 3 frames
* character.
*
* - If you're using a plugin that modifies the number of frames, this plugin
* should be placed before (above).
*
*
*------------------------------------------------------------------------------
* KNOWN ISSUES
*------------------------------------------------------------------------------
*
* -If directional reflection is true and characters or event is facing up, and
* the ground has the bush tag, the reflection may appear wrong.
* If that happens you will have to choose between not using directional
* reflection or not having reflective floor tagged as bush.
*
* - You might possibly encounter a crash with the error message: "cannot read
* property 'pivot' of null", under specific circumstances.
*
* While this is not common, it usually occurs when you've changed an event's
* reflection status while simultaneously altering its graphic —whether by
* playing an animation on the event or by switching its graphic between pages—
* right before the event switches to a new page where the reflection status
* changes (i.e., one page displays the reflection and the other does not).
*
* - If this issue arises, simply add a wait (6 ~ 90 frames) before switching to
* the new event page.
* There is a showcase in the demo with the dead tree's reflection.
*
*
*------------------------------------------------------------------------------
* CHANGE LOG
*------------------------------------------------------------------------------
*
*
* 0.9
* -Added a robuster check to ensure that reflections are only created when the
* character is on a reflective region ID.
* -Added a robuster check to ensure that reflections are only refreshed when
* the character is on a reflective region ID.
* -Strenghtened the method to remove reflections for characters that are no
* longer in reflective regions.
*
* 0.8
* -Added support for Galv_CharacterFrames logic and spritesheet format, as:
* spritesheet%(x).png
* -Simplified character size handling by removing parameters for character width
* and height, and the obsolete <reflect48> Note tag.
* Character dimensions are now automatically calculated.
* -Changed the default wrong value in Reflection Layer from 6 to -1
*
* 0.7
* -Replaced boolean conversion method with JSON.parse for better interpretation.
*
* 0.6
* -Updated variable declarations from var to let and const for better
* consistency.
*
* 0.5
* -Initial release
*
* 0.4 and earlier
* -Experimental and unreleased versions.
*
*
*------------------------------------------------------------------------------
* TERMS
*------------------------------------------------------------------------------
*
* Free to use
* Please do not repost
* I have no relation with Galv and his plugins are available on his website
* https://galvs-scripts.com/2015/10/30/mv-layer-graphics/
* https://galvs-scripts.com/2015/12/12/mv-character-frames/
*
*
*...............................................................................
*/
//==============================================================================
// Initialization Of Paramters
//==============================================================================
(function() {
// Retrieve and store parameters from the plugin manager
const parameters = PluginManager.parameters('808_SWR_SimpleWaterReflect');
// Store plugin parameters globally
window.simpleWaterReflectParams = {
reflectOpacity: Number(parameters['Reflect Opacity'] || 128), // Opacity of the reflection
reflectScale: Number(parameters['Reflect Scale'] || 1), // General scale of the reflection
reflectHorizontalScale: Number(parameters['Reflect Horizontal Scale'] || 1.05), // Horizontal scale of the reflection
reflectVerticalScale: Number(parameters['Reflect Vertical Scale'] || 0.85), // Vertical scale of the reflection
reflectHero: JSON.parse(parameters['Reflect Hero'] || 'false'), // Should the hero reflect?
reflectFollowers: JSON.parse(parameters['Reflect Followers'] || 'false'), // Should followers reflect?
reflectEvents: JSON.parse(parameters['Reflect Events'] || 'false'), // Should events reflect?
waveAmplitude: Number(parameters['Wave Amplitude'] || 2), // Amplitude of the wave effect
waveFrequency: Number(parameters['Wave Frequency'] || 3), // Frequency of the wave effect
distortionAmplitude: Number(parameters['Distortion Amplitude'] || 0), // Amplitude of the distortion effect
distortionFrequency: Number(parameters['Distortion Frequency'] || 0), // Frequency of the distortion effect
rippleAmplitude: Number(parameters['Ripple Amplitude'] || 0), // Amplitude of the ripple effect
rippleFrequency: Number(parameters['Ripple Frequency'] || 0), // Frequency of the ripple effect
reflectionOffset: Number(parameters['Reflection Offset'] || 0), // Offset of the reflection
reflectionAngle: Number(parameters['Reflection Angle'] || 5), // Angle of the reflection
reflectionLayer: Number(parameters['Reflection Layer'] || -1), // Z-index layer of the reflection
directionalReflection: JSON.parse(parameters['Directional Reflection'] || 'false'), // Should reflection follow the character's direction?
reflectRegionsSet: new Set(parameters['Reflect Regions'].split(',').map(Number)) // Set of region IDs where reflections should appear
};
// Shortcuts for global parameters
let reflectOpacity = window.simpleWaterReflectParams.reflectOpacity;
let reflectScale = window.simpleWaterReflectParams.reflectScale;
let reflectHorizontalScale = window.simpleWaterReflectParams.reflectHorizontalScale;
let reflectVerticalScale = window.simpleWaterReflectParams.reflectVerticalScale;
let reflectHero = window.simpleWaterReflectParams.reflectHero;
let reflectFollowers = window.simpleWaterReflectParams.reflectFollowers;
let reflectEvents = window.simpleWaterReflectParams.reflectEvents;
let waveAmplitude = window.simpleWaterReflectParams.waveAmplitude;
let waveFrequency = window.simpleWaterReflectParams.waveFrequency;
let distortionAmplitude = window.simpleWaterReflectParams.distortionAmplitude;
let distortionFrequency = window.simpleWaterReflectParams.distortionFrequency;
let rippleAmplitude = window.simpleWaterReflectParams.rippleAmplitude;
let rippleFrequency = window.simpleWaterReflectParams.rippleFrequency;
let reflectionOffset = window.simpleWaterReflectParams.reflectionOffset;
let reflectionAngle = window.simpleWaterReflectParams.reflectionAngle;
let reflectionLayer = window.simpleWaterReflectParams.reflectionLayer;
let directionalReflection = window.simpleWaterReflectParams.directionalReflection;
const reflectRegionsSet = window.simpleWaterReflectParams.reflectRegionsSet;
// Add functions to get and set the values of directionalReflection and reflectionOffset
window.getDirectionalReflection = function() {
return Boolean(directionalReflection);
};
window.setDirectionalReflection = function(value) {
directionalReflection = value;
};
window.getReflectionOffset = function() {
return reflectionOffset;
};
window.setReflectionOffset = function(value) {
reflectionOffset = value;
};
//==============================================================================
// Reflect Initialization
//==============================================================================
// Create a new reflection layer within the parallax layer
const _Spriteset_Map_createParallax = Spriteset_Map.prototype.createParallax;
Spriteset_Map.prototype.createParallax = function() {
_Spriteset_Map_createParallax.call(this); // Call the original createParallax method
this._reflectionLayer = new Sprite(); // Create a new sprite for reflections
this._baseSprite.addChild(this._reflectionLayer); // Add the reflection layer to the base sprite
this._reflectionLayer.z = reflectionLayer; // Set the Z-index for the reflection layer
};
//==============================================================================
// Plugin Parameters
//==============================================================================
const _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
_Game_Interpreter_pluginCommand.call(this, command, args); // Call the original plugin command method
if (command === 'SetReflectionAngle') {
reflectionAngle = Number(args[0]); // Update reflection angle
// Force a refresh of the reflections
refreshEventReflections.call(SceneManager._scene._spriteset);
} else if (command === 'SetReflect_XScale') {
reflectHorizontalScale = Number(args[0]); // Update horizontal scale factor
refreshEventReflections.call(SceneManager._scene._spriteset);
} else if (command === 'SetReflect_YScale') {
reflectVerticalScale = Number(args[0]); // Update vertical scale factor
refreshEventReflections.call(SceneManager._scene._spriteset);
} else if (command === 'SetReflectionOffset') {
reflectionOffset = Number(args[0]); // Update reflection offset
// Force a refresh of the reflections
refreshEventReflections.call(SceneManager._scene._spriteset);
// Update existing reflections with the new offset
if (SceneManager._scene && SceneManager._scene._spriteset) {
SceneManager._scene._spriteset._reflectionSprites.forEach(function(sprite) {
sprite._yOffset = reflectionOffset; // Adjust the Y offset of the reflection
sprite.y = sprite._character.screenY() + (sprite._character.jumpHeight() || 0) + sprite._yOffset;
});
}
} else if (command === 'SetReflectionLayer') {
reflectionLayer = Number(args[0]); // Update the Z-index layer for reflections
} else if (command === 'SetDirectionalReflection') {
const enabled = (args[0] === 'true'); // Toggle directional reflection on or off
directionalReflection = enabled;
refreshEventReflections.call(SceneManager._scene._spriteset);
} else if (command === 'SetReflectOpacity') {
reflectOpacity = Number(args[0]); // Update reflection opacity
refreshEventReflections.call(SceneManager._scene._spriteset);
// Update existing reflections with the new opacity
if (SceneManager._scene && SceneManager._scene._spriteset) {
SceneManager._scene._spriteset._reflectionSprites.forEach(function(sprite) {
sprite.opacity = reflectOpacity; // Adjust the opacity of the reflection
});
}
} else if (command === 'SetWaveEffect') {
const enabled = (args[0] === 'true');
waveAmplitude = enabled ? Number(parameters['Wave Amplitude'] || 2) : 0;
waveFrequency = enabled ? Number(parameters['Wave Frequency'] || 3) : 0;
// Update existing reflections with the new wave properties
if (SceneManager._scene && SceneManager._scene._spriteset) {
SceneManager._scene._spriteset._reflectionSprites.forEach(function(sprite) {
sprite._waveAmplitude = waveAmplitude; // Adjust the wave amplitude of the reflection
sprite._waveFrequency = waveFrequency; // Adjust the wave frequency of the reflection
});
// Force a refresh of the reflections
refreshEventReflections.call(SceneManager._scene._spriteset);
}
} else if (command === 'SetRippleEffect') {
const enabled = (args[0] === 'true');
rippleAmplitude = enabled ? Number(parameters['Ripple Amplitude'] || 0) : 0;
rippleFrequency = enabled ? Number(parameters['Ripple Frequency'] || 0) : 0;
// Update existing reflections with the new ripple properties
if (SceneManager._scene && SceneManager._scene._spriteset) {
SceneManager._scene._spriteset._reflectionSprites.forEach(function(sprite) {
sprite._rippleAmplitude = rippleAmplitude; // Adjust the ripple amplitude of the reflection
sprite._rippleFrequency = rippleFrequency; // Adjust the ripple frequency of the reflection
});
// Force a refresh of the reflections
refreshEventReflections.call(SceneManager._scene._spriteset);
}
} else if (command === 'SetDistortionEffect') {
const enabled = (args[0] === 'true');
distortionAmplitude = enabled ? Number(parameters['Distortion Amplitude'] || 0) : 0;
distortionFrequency = enabled ? Number(parameters['Distortion Frequency'] || 0) : 0;
// Update existing reflections with the new distortion properties
if (SceneManager._scene && SceneManager._scene._spriteset) {
SceneManager._scene._spriteset._reflectionSprites.forEach(function(sprite) {
sprite._distortionAmplitude = distortionAmplitude; // Adjust the distortion amplitude of the reflection
sprite._distortionFrequency = distortionFrequency; // Adjust the distortion frequency of the reflection
});
// Force a refresh of the reflections
refreshEventReflections.call(SceneManager._scene._spriteset);
}
}
};
//==============================================================================
// Reflection's Graphics Initialization
//==============================================================================
function createCharacterReflection(character) {
const sprite = new Sprite_Character(character); // Create a new sprite for the character's reflection
sprite.opacity = reflectOpacity; // Set the opacity of the reflection
sprite.scale.y = -reflectScale * reflectVerticalScale; // Invert the Y scale for the reflection
sprite.scale.x = reflectHorizontalScale; // Set the horizontal scale of the reflection
sprite.anchor.y = 1; // Anchor the sprite at the bottom
sprite.anchor.x = 0.5; // Anchor the sprite at the horizontal center
sprite._xOffset = 0; // Initialize X offset
sprite._yOffset = reflectionOffset; // Set the initial Y offset based on the reflection offset
sprite.z = reflectionLayer; // Set the Z-index layer of the reflection
// Initialize wave, distortion, and ripple effects with random offsets for variation
sprite._waveOffset = Math.random() * Math.PI * 2;
sprite._waveFrequency = waveFrequency;
sprite._waveAmplitude = waveAmplitude;
sprite._distortionFrequency = distortionFrequency;
sprite._distortionAmplitude = distortionAmplitude;
sprite._rippleFrequency = rippleFrequency;
sprite._rippleAmplitude = rippleAmplitude;
sprite._rippleOffset = Math.random() * Math.PI * 2;
sprite._originalScaleY = sprite.scale.y; // Store the original Y scale for further adjustments
// Set the initial position of the reflection sprite based on the character's position
sprite.x = character.screenX() + sprite._xOffset;
sprite.y = character.screenY() + (character.jumpHeight() || 0) + sprite._yOffset;
return sprite;
}
//==============================================================================
// Direction Facing Behavior
//==============================================================================
// Function to update the reflection's direction and orientation based on the character's direction
function updateReflectionDirection(sprite) {
const character = sprite._character; // Reference to the character associated with the reflection
if (directionalReflection) { // Check if directional reflection is enabled
const direction = character.direction(); // Get the character's current direction
let directionAngle = 0; // Initialize the direction angle
if (sprite.bitmap && sprite.bitmap.isReady()) { // Ensure the sprite's bitmap is ready
const pattern = character.pattern();
const characterIndex = character.characterIndex(); // Get the index of the character on the sprite sheet
const charactersPerRow = 4;
const rowIndex = Math.floor(characterIndex / charactersPerRow); // Calculate the row index of the character on the sprite sheet
const columnIndex = characterIndex % charactersPerRow; // Calculate the column index of the character on the sprite sheet
// Determine the number of frames based on the file name
const fileName = character.characterName();
const frameMatch = fileName.match(/%((d+))/);
const framesPerCharacter = frameMatch ? parseInt(frameMatch[1]) : 3; // Default to 3 frames if not specified
// Frame dimensions
const frameWidth = sprite.bitmap.width / (charactersPerRow * framesPerCharacter);
const frameHeight = sprite.bitmap.height / 8;
switch (direction) { // Edit x and y values for each direction to move the reflection default position
case 4: // Left
sprite.scale.x = reflectHorizontalScale - 0.12; // Set horizontal scale
sprite.scale.y = reflectVerticalScale; // Set vertical scale
directionAngle = -75; // Set angle for left direction
sprite._xOffset = -reflectionOffset - 7; // Adjust X offset
sprite._yOffset = 1; // Adjust Y offset
break;
case 6: // Right
sprite.scale.x = reflectHorizontalScale - 0.12;
sprite.scale.y = reflectVerticalScale;
directionAngle = 75;
sprite._xOffset = reflectionOffset + 7;
sprite._yOffset = 1;
break;
case 8: // Up
sprite.scale.x = reflectHorizontalScale;
directionAngle = 180;
sprite._xOffset = 0;
sprite._yOffset = -reflectionOffset; // Adjust Y offset for up direction
// Set the sprite frame to the front frame when the character is facing up
const directionIndex = 0; // Index for the 'down' direction frame in the sprite sheet
sprite.setFrame((pattern + columnIndex * framesPerCharacter) * frameWidth, (directionIndex + rowIndex * 4) * frameHeight, frameWidth, frameHeight);
sprite.scale.y = -reflectVerticalScale; // Invert the Y scale for the reflection
break;
case 2: // Down
sprite.scale.x = reflectHorizontalScale;
sprite.scale.y = reflectVerticalScale;
directionAngle = 0;
sprite._xOffset = 0;
sprite._yOffset = reflectionOffset;
break;
}
sprite.rotation = (reflectionAngle - directionAngle) * Math.PI / 180; // Apply rotation based on reflection and direction angles
}
} else { // If directional reflection is disabled
if (sprite.bitmap && sprite.bitmap.isReady()) { // Ensure the sprite's bitmap is ready
sprite.rotation = reflectionAngle * Math.PI / 180; // Apply a fixed reflection angle
}
sprite._xOffset = 0; // Reset X offset
sprite._yOffset = reflectionOffset; // Apply parameter Y offset
}
// Update the sprite's position based on the character's current position and offsets
sprite.x = character.screenX() + sprite._xOffset;
sprite.y = character.screenY() + (character.jumpHeight() || 0) + sprite._yOffset;
}
//==============================================================================
// Event's Reflection Conditions
//==============================================================================
function shouldReflectEvent(event) {
let reflectOn = false; // Initialize reflectOn flag
let reflectOff = false; // Initialize reflectOff flag
// Check the note field of the event for reflection tags
const note = event.event().note;
if (/<reflect_on>/i.test(note)) {
reflectOn = true; // Enable reflection if <reflect_on> tag is found
}
if (/<reflect_off>/i.test(note)) {
reflectOff = true; // Disable reflection if <reflect_off> tag is found
}
// If both tags are present, <reflect_off> takes precedence
if (reflectOn && reflectOff) {
reflectOn = false;
console.log("Note tag <reflect_on> & <reflect_off> can't be put together");
}
// Get the active page of the event
const page = event.page();
if (!page) {
return reflectEvents; // If no active page
}
// Check comments on the active page for reflection tags
for (let i = 0; i < page.list.length; i++) {
const command = page.list[i];
if (command.code === 108 || command.code === 408) { // 108 & 408 = Comment codes
const comment = command.parameters[0];
if (/^<reflect_on>$/i.test(comment)) {
reflectOn = true; // Enable reflection if <reflect_on> tag is found
reflectOff = false; // Override any previous reflectOff in Note
}
if (/^<reflect_off>$/i.test(comment)) {
reflectOff = true; // Disable reflection if <reflect_off> tag is found
reflectOn = false; // Override any previous reflectOn
}
}
}
// Determine reflection status based on comments and notes
if (reflectOn) {
return true;
}
if (reflectOff) {
return false;
}
return reflectEvents; // Default to plugin parameters settings if no specific tag found
}
//==============================================================================
// Region ID System
//==============================================================================
// Determines if a character is in a region that allows reflections.
function isInReflectRegion(character) {
const x = character.x; // Get the x-coordinate of the character.
const y = character.y; // Get the y-coordinate of the character.
const regionId = $gameMap.regionId(x, y); // Get the region ID of the tile the character is on.
return reflectRegionsSet.has(regionId); // Check if the region ID is in the set of regions that allow reflections.
}
// Store the original createCharacters function in a variable.
const _Spriteset_Map_createCharacters = Spriteset_Map.prototype.createCharacters;
// Override the createCharacters function.
Spriteset_Map.prototype.createCharacters = function() {
_Spriteset_Map_createCharacters.call(this); // Call the original createCharacters function.
this._reflectionSprites = []; // Initialize an array to store the reflection sprites.
// If the hero should have a reflection...
if (reflectHero && isInReflectRegion($gamePlayer)) {
const heroSprite = createCharacterReflection($gamePlayer); // Create a reflection sprite for the hero.
this._reflectionLayer.addChild(heroSprite); // Add the hero's reflection sprite to the reflection layer.
this._reflectionSprites.push(heroSprite); // Add the hero's reflection sprite to the array of reflection sprites.
}
// If the followers should have reflections...
if (reflectFollowers) {
$gamePlayer.followers().forEach(function(follower) { // For each follower...
if (isInReflectRegion(follower)) { // If the follower is in a region that allows reflections...
const followerSprite = createCharacterReflection(follower); // Create a reflection sprite for the follower.
this._reflectionLayer.addChild(followerSprite); // Add the follower's reflection sprite to the reflection layer.
this._reflectionSprites.push(followerSprite); // Add the follower's reflection sprite to the array of reflection sprites.
}
}, this);
}
// If the events should have reflections...
if (reflectEvents) {
$gameMap.events().forEach(function(event) { // For each event...
if (shouldReflectEvent(event) && isInReflectRegion(event)) { // If the event should have a reflection and is in a region that allows reflections...
const eventSprite = createCharacterReflection(event); // Create a reflection sprite for the event.
this._reflectionLayer.addChild(eventSprite); // Add the event's reflection sprite to the reflection layer.
this._reflectionSprites.push(eventSprite); // Add the event's reflection sprite to the array of reflection sprites.
}
}, this);
}
};
//==============================================================================
// Map Reflection Refresh
//==============================================================================
// Refreshes the reflections for events, hero, and followers.
function refreshEventReflections() {
$gameMap.events().forEach(function(event) {
const shouldReflect = shouldReflectEvent(event) && isInReflectRegion(event);
const existingSprite = this._reflectionSprites.find(function(sprite) {
return sprite._character === event;
});
if (shouldReflect) {
if (!existingSprite) {
// Create and add new reflection if not found
const eventSprite = createCharacterReflection(event);
this._reflectionLayer.addChild(eventSprite);
this._reflectionSprites.push(eventSprite);
}
} else {
if (existingSprite) {
// Remove the reflection if it should no longer be reflected
const spriteIndex = this._reflectionSprites.indexOf(existingSprite);
if (spriteIndex > -1) {
const sprite = this._reflectionSprites.splice(spriteIndex, 1)[0];
if (sprite && sprite.bitmap && sprite.bitmap.isReady()) {
this._reflectionLayer.removeChild(sprite);
sprite.destroy(); // Clean up the sprite
}
}
}
}
}, this);
// Hero
if (reflectHero) {
let heroSprite = this._reflectionSprites.find(function(sprite) {
return sprite._character === $gamePlayer;
});
if (isInReflectRegion($gamePlayer)) {
if (!heroSprite) {
// Create and add new reflection if not found
heroSprite = createCharacterReflection($gamePlayer);
this._reflectionLayer.addChild(heroSprite);
this._reflectionSprites.push(heroSprite);
}
} else {
// Remove the reflection if it should no longer be reflected
if (heroSprite) {
const heroIndex = this._reflectionSprites.indexOf(heroSprite);
if (heroSprite && heroSprite.bitmap && heroSprite.bitmap.isReady()) {
this._reflectionSprites.splice(heroIndex, 1);
this._reflectionLayer.removeChild(heroSprite);
heroSprite.destroy(); // Clean up the sprite
}
}
}
}
// Followers
if (reflectFollowers) {
$gamePlayer.followers().forEach(function(follower) {
const followerSprite = this._reflectionSprites.find(function(sprite) {
return sprite._character === follower;
});
if (isInReflectRegion(follower)) {
if (!followerSprite) {
// Create and add new reflection if not found
const newFollowerSprite = createCharacterReflection(follower);
this._reflectionLayer.addChild(newFollowerSprite);
this._reflectionSprites.push(newFollowerSprite);
}
} else {
// Remove the reflection if it should no longer be reflected
if (followerSprite) {
const followerIndex = this._reflectionSprites.indexOf(followerSprite);
if (followerSprite && followerSprite.bitmap && followerSprite.bitmap.isReady()) {
this._reflectionSprites.splice(followerIndex, 1);
this._reflectionLayer.removeChild(followerSprite);
followerSprite.destroy(); // Clean up the sprite
}
}
}
}, this);
}
}
// Add a flag to control reflection updates
let shouldUpdateReflections = true;
// Override the Scene_Map.prototype.start method
const _Scene_Map_start = Scene_Map.prototype.start;
Scene_Map.prototype.start = function() {
_Scene_Map_start.call(this);
shouldUpdateReflections = true; // Enable reflection updates when returning to the map
};
//==============================================================================
// Reflection's optional Effects
//==============================================================================
const _Spriteset_Map_update = Spriteset_Map.prototype.update;
Spriteset_Map.prototype.update = function() {
_Spriteset_Map_update.call(this);
const time = Date.now() * 0.001;
// Refresh event reflections frequently
if (shouldUpdateReflections && (this._reflectionRefreshTimer === undefined || this._reflectionRefreshTimer <= 0)) {
refreshEventReflections.call(this);
this._reflectionRefreshTimer = 30; // Refresh every x frames (60 = 1 second)
} else if (shouldUpdateReflections) {
this._reflectionRefreshTimer--;
}
if (this._reflectionSprites) {
// Always ensure the hero's reflection is on top
if (reflectHero) {
const heroSprite = this._reflectionSprites.find(function(sprite) {
return sprite._character === $gamePlayer;
});
if (heroSprite) {
this._reflectionLayer.removeChild(heroSprite);
this._reflectionLayer.addChild(heroSprite);
}
}
}
if (this._reflectionSprites) {
this._reflectionSprites.forEach(function(sprite) {
if (sprite._character) {
updateReflectionDirection(sprite);
// Ensure opacity is set
sprite.opacity = reflectOpacity;
// Apply wave effect
const waveScaleFactor = 1 + Math.sin(time * sprite._waveFrequency + sprite._waveOffset) * sprite._waveAmplitude * 0.01;
sprite.scale.y = sprite._originalScaleY * waveScaleFactor;
// Apply distortion effect
if (sprite._distortionAmplitude !== 0 && sprite._distortionFrequency !== 0) {
const distortion = sprite._distortionAmplitude * Math.sin(sprite._distortionFrequency * time);
sprite.scale.y += distortion;
}
// Apply ripple effect
if (sprite._rippleAmplitude !== 0 && sprite._rippleFrequency !== 0) {
const rippleFactor = Math.sin(sprite._rippleFrequency * time + sprite._rippleOffset);
const rippleScale = 1 + rippleFactor * sprite._rippleAmplitude * 0.01;
sprite.scale.y = sprite._originalScaleY * rippleScale;
// Calculate the ripple offset to create an expanding effect
const rippleOffset = rippleFactor * sprite._rippleAmplitude * 0.1;
sprite.y += rippleOffset;
}
if (directionalReflection && (sprite._character.direction() === 4 || sprite._character.direction() === 6)) {
// Apply custom scale after the effects
sprite.scale.y *= (reflectVerticalScale + 0.15);
}
sprite.x = sprite._character.screenX() + sprite._xOffset;
sprite.y = sprite._character.screenY() + (sprite._character.jumpHeight() || 0) + sprite._yOffset;
}
}, this);
}
};
})();
|
808_SWR_LayerZ.js
Spoiler (cliquez pour afficher)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
| /*:
* @plugindesc Adjusts the Z-order of reflection layer to render above Galv's -Z layers in Galv_LayerGraphics.
* @author mugen808
*
* @help
* 808_SWR_LayerZ
*==============================================================================
* This plugin should be placed below both the Simple Water Reflection and
* Galv's layers plugins.
* It will ensure the reflection layer is drawn above Galv's layers with
* negative Z values.
*
* - Requirements:
* Galv_LayerGraphics (on top) (works with 2.0)
* SimpleWaterReflect (middle position) (works with 0.8b)
* This plugin (last position)
*/
(function() {
// Checking dependencies are loaded
function isPluginLoaded(name) {
return !!PluginManager._scripts.find(script => script.toLowerCase() === name.toLowerCase());
}
// Required plugins
if (!isPluginLoaded('808_SWR_SimpleWaterReflect') || !isPluginLoaded('Galv_LayerGraphics')) {
var message = '808_SWR_LayerZ plugin: Required plugins are missing. Ensure both Simple Water Reflection and Galv MV Layer Graphics are active or remove 808_SWR_LayerZ.';
// Show warning
alert(message);
// Log to console
console.warn(message);
return; // Exit the plugin if dependencies are missing
}
// Call parameters from SWR
const parameters = PluginManager.parameters('808_SWR_SimpleWaterReflect');
window.simpleWaterReflectParams = {
reflectOpacity: Number(parameters['Reflect Opacity'] || 128),
reflectScale: Number(parameters['Reflect Scale'] || 1),
reflectHorizontalScale: Number(parameters['Reflect Horizontal Scale'] || 1.05),
reflectVerticalScale: Number(parameters['Reflect Vertical Scale'] || 0.85),
reflectHero: JSON.parse(parameters['Reflect Hero'] || 'false'),
reflectFollowers: JSON.parse(parameters['Reflect Followers'] || 'false'),
reflectEvents: JSON.parse(parameters['Reflect Events'] || 'false'),
waveAmplitude: Number(parameters['Wave Amplitude'] || 2),
waveFrequency: Number(parameters['Wave Frequency'] || 3),
distortionAmplitude: Number(parameters['Distortion Amplitude'] || 0),
distortionFrequency: Number(parameters['Distortion Frequency'] || 0),
rippleAmplitude: Number(parameters['Ripple Amplitude'] || 0),
rippleFrequency: Number(parameters['Ripple Frequency'] || 0),
reflectionOffset: Number(parameters['Reflection Offset'] || 0),
reflectionAngle: Number(parameters['Reflection Angle'] || 5),
reflectionLayer: Number(parameters['Reflection Layer'] || -1),
};
// Function to update reflection layer Z-order
function updateReflectionLayerZ() {
if (Galv && Galv.LG && this._reflectionLayer) {
let maxNegativeZ = -Infinity;
let minPositiveZ = Infinity;
for (const id in this.layerGraphics) {
const zValue = this.layerGraphics[id].z;
if (zValue < 0 && zValue > maxNegativeZ) {
maxNegativeZ = zValue;
}
if (zValue >= 0 && zValue < minPositiveZ) {
minPositiveZ = zValue;
}
}
if (maxNegativeZ > -Infinity) {
this._reflectionLayer.z = maxNegativeZ + 0.5;
} else {
this._reflectionLayer.z = simpleWaterReflectParams.reflectionLayer;
}
if (minPositiveZ < Infinity) {
this._reflectionLayer.z = Math.min(this._reflectionLayer.z, minPositiveZ - 0.5);
}
if (this._reflectionLayer.parent) {
this._reflectionLayer.parent.removeChild(this._reflectionLayer);
}
this._tilemap.addChild(this._reflectionLayer);
}
}
// Override the createParallax method
const _Spriteset_Map_createParallax = Spriteset_Map.prototype.createParallax;
Spriteset_Map.prototype.createParallax = function() {
_Spriteset_Map_createParallax.call(this);
setTimeout(() => updateReflectionLayerZ.call(this), 1000);
};
// Override the update method
const _Spriteset_Map_update = Spriteset_Map.prototype.update;
Spriteset_Map.prototype.update = function() {
_Spriteset_Map_update.call(this);
updateReflectionLayerZ.call(this);
};
})();
|
Change Log:
Spoiler (cliquez pour afficher)
0.9
-Added a more robust check to ensure that reflections are only created when the
character is on a reflective region ID.
-Added a more robust check to ensure that reflections are only refreshed when
the character is on a reflective region ID.
-Strengthened the method to remove reflections for characters that are no
longer in reflective regions.
0.8
-Added support for Galv_CharacterFrames logic and spritesheet format, as:
spritesheet%(x).png
-Simplified character size handling by removing parameters for character width
and height, and the obsolete <reflect48> Note tag.
Character dimensions are now automatically calculated.
-Changed the default wrong value in Reflection Layer from 6 to -1
0.7
-Replaced boolean conversion method with JSON.parse for better interpretation.
0.6
-Updated variable declarations from var to let and const for better
consistency.
0.5
-Initial release
0.4 and earlier
-Experimental and unreleased versions.
Version 0.7 à télécharger ici:
https://drive.google.com/file/d/1371SjZRB_fnL8P7v-8Y5v8cOCqj0kUeo/view?usp=drive_link
________________________________________
| Aller à la page: 1
|
|
|