Skip to content

Commit e19064b

Browse files
authored
create ChangeMap - CloneTokens (Roll20#1010)
Script created to clone PC tokens when changing maps
1 parent 6d3db46 commit e19064b

File tree

2 files changed

+219
-0
lines changed

2 files changed

+219
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
/*
2+
------------------------------------------
3+
Change Map Clone Tokens by Dystopian Djinni
4+
Previous workflow for changing the page is drag player ribbon to new page, copy paste for all the tokens. What a shamozzle!
5+
This script listens to change of page event (drag the ribbon) and will clone player tokens onto the new page. Ignoring duplicate tokens
6+
7+
Considerations:
8+
- 'Player tokens' are tokens that
9+
a.) have a charater sheet
10+
b.) character sheet is controlled by a player.
11+
12+
- 'Player tokens' are assumed to have unique names.
13+
14+
- The spawn coords of the new tokens reflect the original postion of the token on previous map.
15+
------------------------------------------
16+
*/
17+
18+
19+
//variable to hold the player page
20+
var playerPage;
21+
var previousPage;
22+
23+
on("ready",function(){
24+
playerPage = Campaign().get("playerpageid");
25+
previousPage = Campaign().get("playerpageid");
26+
});
27+
28+
29+
//----listen for change of the player ribbon----
30+
on("change:campaign:playerpageid", function(){
31+
32+
previousPage = playerPage;
33+
playerPage = Campaign().get("playerpageid");
34+
movePlayersToPage(playerPage);
35+
36+
});
37+
38+
39+
function movePlayersToPage(pageid){
40+
log("in move players");
41+
42+
var tokens = getPlayerTokens();
43+
var tokensOnNewPage = tokenArrayToNames(getCharTokensOnPage(pageid));
44+
45+
//do a name check of player tokens vs tokens on page.
46+
tokens = tokens.filter(function(token){
47+
return !tokensOnNewPage.includes(token.get("name"));
48+
})
49+
50+
//move split partymembers.
51+
Campaign().set({playerspecificpages:false,playerpageid:pageid});
52+
53+
//create tokens again on new page
54+
createTokens(tokens,pageid);
55+
}
56+
57+
function getPlayerTokens(){
58+
59+
var PCs = findObjs({_type: "character"});
60+
var PCIds = [];
61+
PCs = PCs.filter(character=>character.get("controlledby") != "");
62+
PCs.forEach(function(character){
63+
PCIds.push(character.id);
64+
})
65+
66+
var tokensOnPrevPage = getCharTokensOnPage(previousPage)
67+
.filter(token=>PCIds.includes(token.get("represents")) && token.get("name").length !== 0);
68+
69+
var AllTokens = findObjs({type: "graphic", layer: "objects", subtype: "token"})
70+
.filter(token=>PCIds.includes(token.get("represents")) && token.get("name").length !== 0);
71+
72+
var tokens = [];
73+
var tokensAdded = [];
74+
75+
//adding the tokens found on previous page first because wewant to keep consistent status icons where possible
76+
tokensOnPrevPage.forEach(function(token){
77+
var name = token.get("name");
78+
if (!tokensAdded.includes(name)){
79+
tokens.push(token);
80+
tokensAdded.push(name);
81+
}
82+
});
83+
84+
AllTokens.forEach(function(token){
85+
var name = token.get("name");
86+
if (!tokensAdded.includes(name)){
87+
tokens.push(token);
88+
tokensAdded.push(name);
89+
}
90+
});
91+
return tokens;
92+
}
93+
94+
function getCharTokensOnPage(pageid){
95+
96+
var tokens = findObjs({_type: "graphic", layer: "objects", subtype: "token", pageid: pageid })
97+
.filter(token=>token.get("represents") != "" );
98+
return tokens;
99+
}
100+
101+
function tokenArrayToNames(tokens){
102+
103+
var names = [];
104+
tokens.forEach(function(token){
105+
if(!names.includes(token.get("name"))){
106+
names.push(token.get("name"));
107+
}
108+
})
109+
return names
110+
}
111+
112+
function createTokens(tokens,pageid){
113+
tokens.forEach(function(token){
114+
createToken(token,pageid);
115+
});
116+
}
117+
118+
119+
function createToken(token,pageid,offsetx,represents){
120+
121+
if(offsetx == undefined){ offsetx = 0;}
122+
if(represents == undefined){represents = token.get("represents");}
123+
124+
//src must be thumbnail for some reason
125+
var imgsrc = token.get("imgsrc").replace("max","thumb");
126+
127+
var newToken = {
128+
129+
name: token.get("name"),
130+
controlledby: token.get("controlledby"),
131+
represents: represents,
132+
133+
left: token.get("left")+offsetx,
134+
top: token.get("top"),
135+
width: token.get("width"),
136+
height: token.get("height"),
137+
rotation: token.get("rotation"),
138+
139+
pageid: pageid,
140+
imgsrc: imgsrc,
141+
statusmarkers: token.get("statusmarkers"),
142+
143+
layer: token.get("layer"),
144+
gmnotes: token.get("gmnotes"),
145+
146+
bar1_value: token.get("bar1_value"),
147+
bar1_max: token.get("bar1_max"),
148+
bar1_link: token.get("bar1_link"),
149+
bar2_value: token.get("bar2_value"),
150+
bar2_max: token.get("bar2_max"),
151+
bar2_link: token.get("bar2_link"),
152+
bar3_value: token.get("bar3_value"),
153+
bar3_max: token.get("bar3_max"),
154+
bar3_link: token.get("bar3_link"),
155+
156+
aura1_radius: token.get("aura1_radius"),
157+
aura1_color: token.get("aura1_color"),
158+
aura1_square: token.get("aura1_square"),
159+
aura2_radius: token.get("aura2_radius"),
160+
aura2_color: token.get("aura2_color"),
161+
aura2_square: token.get("aura2_square"),
162+
tint_color: token.get("tint_color"),
163+
164+
showname: token.get("showname"),
165+
showplayers_name: token.get("showplayers_name"),
166+
showplayers_bar1: token.get("showplayers_bar1"),
167+
showplayers_bar2: token.get("showplayers_bar2"),
168+
showplayers_bar3: token.get("showplayers_bar3"),
169+
showplayers_aura1: token.get("showplayers_aura1"),
170+
showplayers_aura2: token.get("showplayers_aura2"),
171+
playersedit_name: token.get("playersedit_name"),
172+
playersedit_bar1: token.get("playersedit_bar1"),
173+
playersedit_bar2: token.get("playersedit_bar2"),
174+
playersedit_bar3: token.get("playersedit_bar3"),
175+
playersedit_aura1: token.get("playersedit_aura1"),
176+
playersedit_aura2: token.get("playersedit_aura2"),
177+
light_radius: token.get("light_radius"),
178+
light_dimradius: token.get("light_dimradius"),
179+
light_otherplayers: token.get("light_otherplayers"),
180+
light_hassight: token.get("light_hassight"),
181+
light_angle: token.get("light_angle"),
182+
light_losangle: token.get("light_losangle"),
183+
light_multiplier: token.get("light_multiplier"),
184+
has_bright_light_vision: token.get("has_bright_light_vision"),
185+
has_night_vision: token.get("has_night_vision"),
186+
night_vision_distance: token.get("night_vision_distance"),
187+
emits_bright_light: token.get("emits_bright_light"),
188+
bright_light_distance: token.get("bright_light_distance"),
189+
emits_low_light: token.get("emits_low_light"),
190+
low_light_distance: token.get("low_light_distance"),
191+
};
192+
createObj("graphic",newToken);
193+
}
194+
195+
196+
197+
198+

ChangeMap_CloneTokens/script.json

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "Change Map - Clone Tokens",
3+
"script": "ChangeMapCloneTokens.js",
4+
"version": "1.0",
5+
"description": "This script listens for change of page event (drag the ribbon) and will clone player tokens onto the new page. Ignoring duplicate tokens by name.\nPrevious workflow for changing the page is drag player ribbon to new page then copy paste for all the tokens. What a shamozzle!\n/nConsiderations:/n- 'Player tokens' are tokens that/na.) have a charater sheet/nb.) character sheet is controlled by a player./n/n- 'Player tokens' are assumed to have unique names./n/n- The spawn coords of the new tokens reflect the original postion of the token on previous map.",
6+
"authors": "Dystopian Djinni",
7+
"roll20userid": "2047875",
8+
"patreon": "",
9+
"useroptions": [{}],
10+
"dependencies": [],
11+
"modifies": {
12+
"Campaign.playerpageid": "read,write",
13+
"Campaign.playerspecificpages": "read,write",
14+
"Page.name": "read",
15+
"token":"read,write",
16+
"character": "read",
17+
"state.MapChange": "read"
18+
},
19+
"conflicts": [],
20+
"previousversions": []
21+
}

0 commit comments

Comments
 (0)