Scripting: allow precise and safe control of peep animations#21913
Conversation
cebcf48 to
f2756b7
Compare
|
I am testing it right now, but the peep (guest or staff) keeps their animation on 'walking'. It looks like it's state is preventing the animation from executing, but I need @AaronVanGeffen or @Basssiiie to confirm that. |
|
Could you share the code you're using to test? Edit: I had added a call to |
a408185 to
fc3b597
Compare
|
Funnily enough, both @Manticore-007 and I were testing with the 'picked up' sprite for peeps and staff members, and were surprised at how much it was glitching. Turns out these sprites do not have four rotations, so we were incorrectly offsetting into them. Of course, these sprites were meant to be drawn under the mouse pointer, and never meant to be used for walking peeps! 😄 I have changed |
|
So what’s the status here? |
|
Ready to go, as far as I'm concerned. I believe @Manticore-007 has been experimenting a bunch already, too. Let's wait for him and @Basssiiie to comment. Probably good to increment the plugin version before merging, as a means of feature detection. |
|
Leaving this here so I don't forget: @Manticore-007 has asked for an extra property/function to get a peep's walking animation sprite ids. Should be very doable for this PR. |
If it is easy to implement, I would love to use them in the first tab of the Peep Editor just like the first tab when clicking a guest or staff member, so I need the colours of the selected peep too. But this is just some luxury thingy, nothing practical. And apologies for responding slow, I'm not used to communicating via GitHub that much yet. |
|
Well, I have added a method for obtaining the walking animation sprite ids. I couldn't resist finishing that up today 😄
I believe this information is already exported. Consider the following property for Staff: interface Staff extends Peep {
/**
* Colour of the staff member. Not applicable for entertainers.
*/
colour: number;For Guests, the following two properties are available: interface Guest extends Peep {
/**
* Colour of the guest's t-shirt.
*/
tshirtColour: number;
/**
* Colour of the guest's trousers.
*/
trousersColour: number; |
Basssiiie
left a comment
There was a problem hiding this comment.
I'll have a test later as well.
Did you plan on adding the flag to block a guest's state in this PR as well, or is that for a later PR? So they don't regain energy after being frozen or get included in the park rating. Because IMHO that'd be quite crucial for actually using the guest animations API. 🙂
That is something for a future PR, yes. I don't want to change the core peep logic in this PR. You can already use this code as-is, though. Peeps retain their animation as long as they don't change action. They just don't support freezing yet. |
c679256 to
048c08a
Compare
|
#21920 fixes that, right? |
|
Yep, that's what the other PR is for, indeed 😁 |
There was a problem hiding this comment.
I've had a test and found a few issues with guest sprites:
-
getAnimationSpritesreturns the entire animation timeline including duplicate spirtes, butanimationOffsetis not an offset into that timeline, but merely an offset into the spritesheet. This is especially visible with non-repeating animations likeclap,drowningetc. -
Setting the animation to
eatFoodorsittingEatFoodwithout a food item gets the animation of the peep crossing its arms (either sitting or not), an animation that is not in the list otherwise? (Is this intended?) -
Getting
animationreturnswalkingfor guests sitting on benches with food items instead when sitting still. (See image below)
-
animationandgetAnimationSpritesreturn animations forwalkingwhen the guest is standing still in a queue with a sprite that seems to not be in the sprites list. -
getAnimationSpriteson guests with an umbrella or hat returns sprites with a headless guest and no umbrella (when raining) or hat. Balloons are also missing for guests with balloons.
All the API's for staff members seem to be alright, I could not find any issues there.
As is usual, click here for my test script. 🙂
registerPlugin({
name: "Test peep anims",
version: "1",
authors: ['Basssiiie'],
targetApiVersion: 82,
type: "local",
licence: "MIT",
main()
{
ui.registerMenuItem("Test peep anims", function()
{
ui.activateTool({
id: "test-peep-anims",
cursor: "cross_hair",
onDown: function(args)
{
var id = args.entityId;
if (id == undefined) return;
var peep = map.getEntity(id);
if (peep.type !== "guest" && peep.type !== "staff") return;
var anims = peep.availableAnimations;
var shopItems = [
"balloon", "hat", "map", "sunglasses", "toy", "tshirt", "umbrella", "photo1", "photo2", "photo3",
"photo4", "voucher", "beef_noodles", "burger", "candyfloss", "chicken", "chips", "chocolate", "cookie",
"doughnut", "hot_dog", "fried_rice_noodles", "funnel_cake", "ice_cream", "meatball_soup", "pizza", "popcorn",
"pretzel", "roast_sausage", "sub_sandwich", "tentacle", "toffee_apple", "wonton_soup", "coffee", "drink",
"fruit_juice", "iced_tea", "lemonade", "soybean_milk", "sujeonggwa"
];
var window = ui.openWindow({
classification: "test-peep-anims",
title: "Peep anims",
width: 210,
height: 300,
maxWidth: 2000,
maxHeight: 300,
onUpdate: function()
{
var animShow = window.findWidget("anim-show");
var animOffset = window.findWidget("anim-offset");
var animLength = window.findWidget("anim-length");
animShow.text = "Animation: " + peep.animation;
animOffset.text = String(peep.animationOffset);
animLength.text = "Length: " + peep.animationLength;
},
widgets: [
{
type: "label",
x: 5,
y: 20,
width: 200,
height: 15,
text: "Name: " + peep.name
},
{
name: "anim-show",
type: "label",
x: 5,
y: 40,
width: 200,
height: 15,
text: "Animation: " + peep.animation
},
{
type: "dropdown",
x: 5,
y: 60,
width: 200,
height: 15,
items: anims,
onChange: function(index)
{
peep.animation = anims[index];
}
},
{
name: "anim-offset",
type: "textbox",
x: 5,
y: 80,
width: 200,
height: 15,
text: String(peep.animationOffset),
onChange: function(text)
{
peep.animationOffset = Number.parseInt(text);
}
},
{
name: "anim-length",
type: "label",
x: 5,
y: 100,
width: 200,
height: 15,
text: "Length: " + peep.animationLength
},
{
type: "dropdown",
x: 5,
y: 120,
width: 200,
height: 15,
items: shopItems,
onChange: function(index)
{
peep.removeAllItems();
peep.giveItem({ type: shopItems[index] });
}
},
{
type: "custom",
x: 5,
y: 140,
width: 2000,
height: 150,
onDraw: function(gfx)
{
var y = 0;
for (var rot = 0; rot < 4; rot++)
{
var sprites = peep.getAnimationSpriteIds(peep.animation, rot);
var x = 0;
var height = 0;
for (var idx = 0; idx < sprites.length; idx++)
{
var sprite = sprites[idx];
var image = gfx.getImage(sprite);
gfx.image(sprite, x - image.offset.x, y - image.offset.y);
x += image.width + 5;
height = Math.max(height, image.height);
}
y += height + 5;
}
}
},
]
})
}
})
})
}
});
Fixed. The getter now returns the animation offset rather than the sprite image offset. Looking at the code, the setter already worked correctly.
It probably won't surprise you that the script engine just maps Honestly, I'm not sure sure if and how these 'arms crossed' sprites are used in the state machine, internally. If we figure that out, we could add another alias for it. Similarly, Something we can refine later on as well, as far as I'm concerned.
This is an odd one that I haven't narrowed down. Perhaps
Well spotted. It seems queueing may be handled differently from the regular animations. I'm not sure how to go about this. Any suggestions?
This is because the hat, umbrella, and balloon sprites are actually rendered separately. The guest sprites already have a primary and secondary colour set for their shirts and trousers. It seems the item sprites are rendered separately to make them independently recolourable. Not something we can change with the current set-up, as you can imagine. |
I can agree with having most of the points mentioned for another time or another PR, except for this one. I can imagine a player user would like to know if a guest is sitting on a bench or not in some way or another, and it'd be weird if |
|
@Basssiiie You're right. It seems it is more complicated than I would like, though. Consider the following code excerpt from OpenRCT2/src/openrct2/entity/Guest.cpp Lines 1278 to 1289 in c8ec8a5 Note how As I don't want to change the state machine, I have come up with a compromise that adds an exception just for idle, sitting peeps. It's not the nicest, but it works:
|
32688f9 to
7e219bf
Compare
|
Time to merge, could you add a changelog entry? |
|
I'd like a go-ahead from @Basssiiie first, if you don't mind. The other peep scripting PR, #21714, is ready to go, though. Let's deal with that first, and rebase this one after, shall we? |
7e219bf to
94dd2d9
Compare
Basssiiie
left a comment
There was a problem hiding this comment.
LGTM! Thanks for your efforts and patience! 😄
- Feature: [#622] Add option to align the top toolbar buttons horizontally centred (off by default). - Feature: [#20263] Ability to increase the size of the map in the (0, 0) direction. - Feature: [#21714] [Plugin] Costume assignment is now tailored to each staff type. - Feature: [#21853] Enlarged UI mode. - Feature: [#21893, #22065] On launch, the game now indicates what system is being initialised. - Feature: [#21913] [Plugin] Allow precise and safe control of peep animations. - Feature: [#22046] [Plugin] Add interface for crashed vehicle particle. - Feature: [#22085] [Plugin] The result of actions that create banners now includes the bannerIndex. - Feature: [#22087] [Plugin] Expose guests’ favourite rides to the plugin API. - Feature: [#22090] [Plugin] Allow writing of paused state in non-networked settings. - Feature: [#22140] Add option to automatically close dropdown menus if Enlarged UI is enabled. - Feature: [#22150] [Plugin] Expose monthly expenditure history to the plugin API. - Feature: [#22210] [Plugin] Peeps can now be made stationary or completely frozen. - Feature: [#22210] [Plugin] The direction in which a peep is facing can now be manipulated. - Improved: [#19870] Allow using new colours in UI themes. - Improved: [#21774] The Alpine Coaster now supports using the alternative colour schemes. - Improved: [#21853] Dropdowns now automatically use multiple columns if they are too tall for the screen. - Improved: [#21981] Rendering performance of the map window has been improved considerably. - Improved: [#21981] The map window now defaults to showing as much of the map as fits the screen. - Improved: [#21983] Taking a screenshot now shows a message again, closing when taking another. - Improved: [#22026] The options window now stays centred when window scaling is changed. - Improved: [#22060] [Plugin] The scroll wheel can now be used to modify spinner widget values in custom/script windows. - Improved: [#22065] Joining a network game now indicates progress using coaster trains. - Improved: [#22075] [Plugin] Plugins can now use G1 Icons. - Improved: [#22084] The game now temporarily pauses while the load/save window is open. - Improved: [#22217] See-through items are ignored again in viewport/pointer interaction. - Improved: [objects#238] Add preview image for invisible queue. - Improved: [objects#329] Add RCT1AA lay-down coaster trains (for import only). - Change: [#7248] Small mini-maps are now centred in the map window. - Change: [#20240] Heavy snow and blizzards now make guests buy and use umbrellas. - Change: [#21043] The new music styles are no longer added to old parks automatically. - Change: [#21214] Wacky Worlds and Time Twister’s scenario names now match their park names. - Change: [#21991] UI themes JSON now use colour names and a translucency bool, instead of a number (old themes still work). - Change: [#22057] Reorder Time Twister’s scenarios and adjust their difficulty classification. - Change: [#22173] Patrol path selection is visible over existing patrol paths. - Change: [#22196] Make track navigation buttons holdable. - Change: [#22227] [Plugin] Ride prices are now constrained for plugins as well. - Fix: [#13234] Vehicle weight sometimes wrong after using Remove All Guests cheat. - Fix: [#13294] Map corners are cut off in some directions (original bug). - Fix: [#14630] Non-ASCII thousands and decimal separators not processed correctly. - Fix: [#21496] Some RCT1 scenery is hidden after saving and reloading. - Fix: [#21533] Support glitches on Hybrid Coaster. - Fix: [#21974] No reason specified when attempting to place benches, lamps, or bins on path with no unconnected edges (original bug). - Fix: [#21987] [Plugin] API cannot handle negative removal prices. - Fix: [#22008] Uninverted Lay-down roller coaster uses the wrong support type. - Fix: [#22012] [Plugin] Images on ImgButton widgets cannot be updated. - Fix: [#22121] Some news items in the “Recent Messages” window have the wrong text colour. - Fix: [#22152] [Plugin] Negative signed integers are truncated. - Fix: [#22161] Using arrow keys in textboxes crashes the game. - Fix: [#22174] Cheats are reset when starting a server. - Fix: [#22185] Intensity and nausea are incorrectly sorted in the rides list after ratings invalidation. - Fix: [#22226] Red traffic light shows incorrect sprite when pressed. - Fix: [objects#323] Incorrect wall boundaries on large WW/TT scenery objects. - Fix: [objects#331] Incorrect hover car capacity string. - Fix: [objects#334] Incorrect school bus capacity string. - Fix: [objects#337] Swan Boats use an incorrect third remap colour (original bug).
Release v0.4.12 - Feature: [OpenRCT2#622] Add option to align the top toolbar buttons horizontally centred (off by default). - Feature: [OpenRCT2#20263] Ability to increase the size of the map in the (0, 0) direction. - Feature: [OpenRCT2#21714] [Plugin] Costume assignment is now tailored to each staff type. - Feature: [OpenRCT2#21853] Enlarged UI mode. - Feature: [OpenRCT2#21893, OpenRCT2#22065] On launch, the game now indicates what system is being initialised. - Feature: [OpenRCT2#21913] [Plugin] Allow precise and safe control of peep animations. - Feature: [OpenRCT2#22046] [Plugin] Add interface for crashed vehicle particle. - Feature: [OpenRCT2#22085] [Plugin] The result of actions that create banners now includes the bannerIndex. - Feature: [OpenRCT2#22087] [Plugin] Expose guests’ favourite rides to the plugin API. - Feature: [OpenRCT2#22090] [Plugin] Allow writing of paused state in non-networked settings. - Feature: [OpenRCT2#22140] Add option to automatically close dropdown menus if Enlarged UI is enabled. - Feature: [OpenRCT2#22150] [Plugin] Expose monthly expenditure history to the plugin API. - Feature: [OpenRCT2#22210] [Plugin] Peeps can now be made stationary or completely frozen. - Feature: [OpenRCT2#22210] [Plugin] The direction in which a peep is facing can now be manipulated. - Improved: [OpenRCT2#19870] Allow using new colours in UI themes. - Improved: [OpenRCT2#21774] The Alpine Coaster now supports using the alternative colour schemes. - Improved: [OpenRCT2#21853] Dropdowns now automatically use multiple columns if they are too tall for the screen. - Improved: [OpenRCT2#21981] Rendering performance of the map window has been improved considerably. - Improved: [OpenRCT2#21981] The map window now defaults to showing as much of the map as fits the screen. - Improved: [OpenRCT2#21983] Taking a screenshot now shows a message again, closing when taking another. - Improved: [OpenRCT2#22026] The options window now stays centred when window scaling is changed. - Improved: [OpenRCT2#22060] [Plugin] The scroll wheel can now be used to modify spinner widget values in custom/script windows. - Improved: [OpenRCT2#22065] Joining a network game now indicates progress using coaster trains. - Improved: [OpenRCT2#22075] [Plugin] Plugins can now use G1 Icons. - Improved: [OpenRCT2#22084] The game now temporarily pauses while the load/save window is open. - Improved: [OpenRCT2#22217] See-through items are ignored again in viewport/pointer interaction. - Improved: [objects#238] Add preview image for invisible queue. - Improved: [objects#329] Add RCT1AA lay-down coaster trains (for import only). - Change: [OpenRCT2#7248] Small mini-maps are now centred in the map window. - Change: [OpenRCT2#20240] Heavy snow and blizzards now make guests buy and use umbrellas. - Change: [OpenRCT2#21043] The new music styles are no longer added to old parks automatically. - Change: [OpenRCT2#21214] Wacky Worlds and Time Twister’s scenario names now match their park names. - Change: [OpenRCT2#21991] UI themes JSON now use colour names and a translucency bool, instead of a number (old themes still work). - Change: [OpenRCT2#22057] Reorder Time Twister’s scenarios and adjust their difficulty classification. - Change: [OpenRCT2#22173] Patrol path selection is visible over existing patrol paths. - Change: [OpenRCT2#22196] Make track navigation buttons holdable. - Change: [OpenRCT2#22227] [Plugin] Ride prices are now constrained for plugins as well. - Fix: [OpenRCT2#13234] Vehicle weight sometimes wrong after using Remove All Guests cheat. - Fix: [OpenRCT2#13294] Map corners are cut off in some directions (original bug). - Fix: [OpenRCT2#14630] Non-ASCII thousands and decimal separators not processed correctly. - Fix: [OpenRCT2#21496] Some RCT1 scenery is hidden after saving and reloading. - Fix: [OpenRCT2#21533] Support glitches on Hybrid Coaster. - Fix: [OpenRCT2#21974] No reason specified when attempting to place benches, lamps, or bins on path with no unconnected edges (original bug). - Fix: [OpenRCT2#21987] [Plugin] API cannot handle negative removal prices. - Fix: [OpenRCT2#22008] Uninverted Lay-down roller coaster uses the wrong support type. - Fix: [OpenRCT2#22012] [Plugin] Images on ImgButton widgets cannot be updated. - Fix: [OpenRCT2#22121] Some news items in the “Recent Messages” window have the wrong text colour. - Fix: [OpenRCT2#22152] [Plugin] Negative signed integers are truncated. - Fix: [OpenRCT2#22161] Using arrow keys in textboxes crashes the game. - Fix: [OpenRCT2#22174] Cheats are reset when starting a server. - Fix: [OpenRCT2#22185] Intensity and nausea are incorrectly sorted in the rides list after ratings invalidation. - Fix: [OpenRCT2#22226] Red traffic light shows incorrect sprite when pressed. - Fix: [objects#323] Incorrect wall boundaries on large WW/TT scenery objects. - Fix: [objects#331] Incorrect hover car capacity string. - Fix: [objects#334] Incorrect school bus capacity string. - Fix: [objects#337] Swan Boats use an incorrect third remap colour (original bug).



This PR introduces methods for scripts to precisely and safely control the animation frames used to render guests and staff members. This may be used to compose intricate dioramas using peeps. However, the guests and staff have to be rendered immobile, or they will carry on with whatever they were doing, resetting their sprite.
Guests have more animations available than staff members. In turn, animations available to staff differs based on the staff type. To see what animations can be used, scripts can use the
animationsAvailableproperty, which exists for both guests and staff.A future PR may introduce functionality to control peeps' actions as well. However, this would have to touch core peep logic, which is less desirable.
Another request was to allow scripts to manage guests items, including food and drinks. I believe this has already been introduced in #21062.
NB: I wrote this while on public transport, so it could do with a fair bit of testing, still.
@Basssiiie and @Manticore-007, this one's for you.