Custom Phone Calls

Phone calls within Sims 2, from what I've been able to figure out, are convoluted, complex and completely modder unfriendly!

A phone call requires at least two objects - a phone call object and one or more phone call sub-objects. All of which have "is global sim object" set to 0x0001 (entry 0x002A in the OBJD)

All phone call objects have a Selector Category value (entry 0x004B in the OBJD) of 0x0091 and include the objects "Phone Call - Business", "Phone Call - College", "Phone Call - Delivery", "Phone Call - Emergency" etc. According to global BCONs 0x0106 "Category" and 0x016C "Category2", Selector Category 0x0091 is "Phone Call Type"

All phone call obects also set their Selector Sub-Category value (entry 0x004C in the OBJD). The sub-category is then used to identify all the associated phone call sub-objects. For example, "Phone Call - Delivery" has a sub-category value of 0x0088 (which from global BCON 0x016C is "Phone Call Type - Delivery") and if we find all the objects with a Selector Category value of 0x0088, we locate "Phone Call - Delivery - Pizza" (0x0088/0x0000), "Phone Call - Delivery - Groceries" (0x0088/0x0001) and "Phone Call - Delivery - Chinese Takeout" (0x0088/0x0002)

For a Sim to call another Sim the phone call object is "Phone Call - Sim2Sim" (0x0091/0x008E) with sub-objects such as "Phone Call - Sim2Sim - Crank Call" (0x008E/0x0001) and "Phone Call - Sim2Sim - Date Call" (0x008E/0x004)

Naively I thought that adding a new Sim2Sim call would be as simple as cloning the crank-call object, changing its sub-category to something that wasn't used and adding my new code. HA!

Turns out the "Phone Call - Sim2Sim" object is completely hard-coded to only recognise/enable the standard Sim2Sim sub-phone calls and even these have so much legacy code/foibles in them that they are pretty much useless as a starting point.

No problem, we'll just clone a phone call object such as "Phone Call - Delivery" (0x0091/0x0088) and set its category to something unused (0x00EE say). Then we can clone one of its sub-phone call objects (eg "Phone Call - Delivery - Pizza" (0x0088/0x0000)), set that's category to be the same as the phone call object (0x00EE in this example) and its sub-category to 0x0000, and finally add our code to that. No such luck!

Turns out the PhoneCallGlobals semi-global BHAV "Call - Build Menu" (0x2050) is hard-coded for the standard phone call sub-category values, so to get anything to work, we're going to have to mod that.

What we ideally want to do is use primitive 0x001F "Set to Next (obj with cat == temp 0, returns GUID in Temp 2,3)" with Temp0 = 0x0091 to iterate all phone call objects, discard any that have a sub-category between 0x0080 and 0x0090 inclusive and then run "CT - Phone Call Available?" on each remaining object. Ummm! Couldn't get that to work, there is something going on with Temp1 controlling the sub-category with that particular flavour of "Set to Next".

The compromise is to loop from 0x00DC (the first unused category according to BCON 0x016C "Category2") to 0x00FF inclusive and call BHAV "Call - Check Type Availability" (0x204D) to locate any phone call sub-objects. It's not ideal, but a) it works, b) changes are restricted to only one BHAV, and c) it doesn't impact on any existing phone call objects.

With the hacked semi-global BHAV, we can now create our new phone call object and sub-object(s). We need to pick a category value to use - so there is a chance of a conflict between mods here. The generic object I've created has the category defined in a BCON, so if there is a conflict, all a user would need to do is pick an unused value from all their phone call mods and change the value in the OBJD and BCON.

To make a new phone call object from the WH_PhoneCall_Generic.package file

  • Copy and rename the package file
  • BCON 0x1000:0x00 - pick an unused category value between 0x00DC and 0x00FF inclusive
  • OBJD - change the name, change GUID and Orig. GUID, and change Selector Sub-Category (entry 0x004C) to the same value as BCON 0x1000:0x00

The phone-call sub-object(s) are a combination of generic and custom code. The generic sub-object I've created has the category and sub-category defined in a BCON, so when the category conflicts, all a user would need to do is change the category value in the OBJD and BCON to match that of the associated phone call object.

To make a new phone call sub-object from WH_PhoneCall_Generic_SubCall.package file

  • Copy and rename the package file
  • BCON 0x1000:0x00 - set to the same value as the phone call object
  • BCON 0x1000:0x01 - set to a unique value within the phone call set (it is recommended, but not necessary, to use sequential values from 0x0000)
  • BHAV 0x1008 - add code to determine if the phone call can be made
  • BHAV 0x1009 - add code to handle the phone call
  • OBJD - change the name, change GUID and Orig. GUID, change Selector Category (entry 0x004B) to the same value as BCON 0x1000:0x00, and change Selector Sub-Category (entry 0x004C) to the same value as BCON 0x1000:0x01
  • STR# 0x012E:0x00 - change the text to something appropriate

If the phone call only affects the dialing Sim, you're pretty much home and dry as it's easy to use their My, OID and NID values. However, if the dialing Sim needs to interact with another Sim (who, by definition, will not be on the current lot) the situation is a lot more complex. When a Sim (the caller) dials an off-lot Sim (the callee) we only have the NID for the callee Sim. In some cases that may be enough, but if you need their OID, for example, to make them the subject of a memory, you will need to use primitive 0x002A "Create New Object Instance (Neighbour in stack object, place: out of world)" and manage the off-world object - this is how Maxis do it for "Call.../Sim.../Just Talk" - see BHAV "Talk - Start Talking" (0x200C) in the PhoneCallGlobals (0x7FBD3903) group. If you need the My object for the callee Sim (for example, to satisify wants/fears), the easiest way to do this is to add TTAB and TTAs entries to the phone call sub-object and use primitive 0x000D "Push Interaction" with the target interaction set to "Immediate".

Well, that's the theory. I'm hitting an issue where my OOW callee Sim is being removed outside of my control. This occasionally causes the cascading nature of wants/fears to fail, or the broadcast feature of memories to fail, as the callee Sim has been removed by the time the associated BHAVs execute and their OID is no longer valid. I may end up hacking the two semi-global BHAVs where the invalid OID causes an error to just silently fail.

Hope these notes are of use to someone. Enjoy!


Files