mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-12 19:22:56 +00:00
I have done lots of work to make selecting players for special roles be fair.
- New options preferences: "be traitor", "be changeling" and so on for all special roles.
- Now you can have job of AI/cyborg in preferences and do not lower your chances to become wizard/changeling/etc. And vice-versa: you do not have to select AI in your preferences to have non zero chance to play malf.
- Jobban from syndicate bans player from any special role (including malf AI, cult, etc).
- Fixed bug with changeling round not ending sometimes.
- All special roles were tuned to work better as admin-driven event.
-- All adminmade special characters will be listed at the end of round of any type.
-- All adminmade special characters are fully functional with following exceptions:
--- The ending conditions are determined at round start, i.e. you cannot end revolution by killing wizards and malf AIs (however, with nuke you can end anything).
--- The cultists cannot get their special objectives.
--- The malf AI can hack the APCs but without any profit.
--- The syndicate operatives must obtain the nuke/working code from admins.
--- As before, nuclear explosion ends round. Even if nuke was used in wrong place.
- Fixed thingy like "Not enough players for revolution game mode. Restarting world in 5 seconds."
- Changeling wont get objective "absorb X genomes" when there are less that X players in game.
- proc/equip_if_possible now has return value, procs like equip_revolutionary (giving a flash) should be more reliable.
- There are no fake wizards anymore. The research staff have to kill ALL wizards on order to win, even adminspawned ones. ("give spell" verb works as before, not making a spellcaster to actually be wizard).
- The semi-new game mode: traitor+changeling. Just like regular traitor mode plus one changeling. Round ends when the shuttle reaches centcom. Option for config.txt: "PROBABILITY TRAITORCHAN".
- Successful malf AI now have 60 seconds to choose to explode the station or not (some players still have to rejoin game to have their new verbs shown in Malfunction tab).
- Monkeys mode fixed, monkeys wouldn't randomly cure anymore.
For admins:
- New powerful mind editor oriented to mixed rounds.
-- Setting someone as special character (like wizard) does not equip him/her automatically. You have to do it it next step. Note, that in case of wizards and nuke operatives their old dress will be deleted! If you do not want it you shall use "undress" link.
-- Only operatives, head revs and cultists have their objectives set immediately.
-- You can unemad borgs!
-- You cannot unemag borgs because calling mind editor for nonhumans is blocked atm.
-- many other useful features.
-- you can fix burned out flashes from mind editor.
-- first assign the new malf AI/wizard then demalf/dewizard old one or round will immediately end.
- if delete the nuke bomb during its downcounting round will stuck. Using "edit ticker variables" set ticker.mode.explosion_in_progress = 0.
For coders:
- /datum/game_mode/malfunction/AI_Module renamed to /datum/AI_Module. Reason: What. The. Fuck.
Unrelated fixes:
- Blueprints can create areas up to 300 tiles (was 100).
- Cyborgs wont leave backpacks at spawn point anymore.
- Fixed bug in preferences causing preferences files to be huge.
- Diseases can infect again.
- The option "SQL_ENABLED 0" now works in config.txt.
- fixed critical bug on assassinate objective.
Bugs:
- We have a bug with job distribution for people who haven't any available jobs in their preferences. Players tends to group by jobs.
- For example, if we have 3 players they with hight chances will got same jobs. And probability of having one engineer and one medic _exactly_ equals _zero_.
- I am not sure if my changes made that bug worse. Anyway I MUST do this commit. Bug will be fixed eventually. Maybe.
git-svn-id: http://tgstation13.googlecode.com/svn/trunk@1703 316c924e-a436-60f5-8080-3fe189b3f50e
278 lines
9.3 KiB
Plaintext
278 lines
9.3 KiB
Plaintext
/*
|
|
HOW IT WORKS
|
|
|
|
The radio_controller is a global object maintaining all radio transmissions, think about it as about "ether".
|
|
Note that walkie-talkie, intercoms and headsets handle transmission using nonstandard way.
|
|
procs:
|
|
|
|
add_object(obj/device as obj, var/new_frequency as num, var/filter as text|null = null)
|
|
Adds listening object.
|
|
parameters:
|
|
device - device receiving signals, must have proc receive_signal (see description below).
|
|
one device may listen several frequencies, but not same frequency twice.
|
|
new_frequency - see possibly frequencies below;
|
|
filter - thing for optimization. Optional, but recommended.
|
|
All filters should be consolidated in this file, see defines later.
|
|
Device without listening filter will receive all signals (on specified frequency).
|
|
Device with filter will receive any signals sent without filter.
|
|
Device with filter will not receive any signals sent with different filter.
|
|
returns:
|
|
Reference to frequency object.
|
|
|
|
remove_object (obj/device, old_frequency)
|
|
Obliviously, after calling this proc, device will not receive any signals on old_frequency.
|
|
Other frequencies will left unaffected.
|
|
|
|
return_frequency(var/frequency as num)
|
|
returns:
|
|
Reference to frequency object. Use it if you need to send and do not need to listen.
|
|
|
|
radio_frequency is a global object maintaining list of devices that listening specific frequency.
|
|
procs:
|
|
|
|
post_signal(obj/source as obj|null, datum/signal/signal, var/filter as text|null = null, var/range as num|null = null)
|
|
Sends signal to all devices that wants such signal.
|
|
parameters:
|
|
source - object, emitted signal. Usually, devices will not receive their own signals.
|
|
signal - see description below.
|
|
filter - described above.
|
|
range - radius of regular byond's square circle on that z-level. null means everywhere, on all z-levels.
|
|
|
|
obj/proc/receive_signal(datum/signal/signal, var/receive_method as num, var/receive_param)
|
|
Handler from received signals. By default does nothing. Define your own for your object.
|
|
Avoid of sending signals directly from this proc, use spawn(-1). Do not use sleep() here please.
|
|
parameters:
|
|
signal - see description below. Extract all needed data from the signal before doing sleep(), spawn() or return!
|
|
receive_method - may be TRANSMISSION_WIRE or TRANSMISSION_RADIO.
|
|
TRANSMISSION_WIRE is currently unused.
|
|
receive_param - for TRANSMISSION_RADIO here comes frequency.
|
|
|
|
datum/signal
|
|
vars:
|
|
source
|
|
an object that emitted signal. Used for debug and bearing.
|
|
data
|
|
list with transmitting data. Usual use pattern:
|
|
data["msg"] = "hello world"
|
|
encryption
|
|
Some number symbolizing "encryption key".
|
|
Note that game actually do not use any cryptography here.
|
|
If receiving object don't know right key, it must ignore encrypted signal in its receive_signal.
|
|
|
|
*/
|
|
|
|
/*
|
|
Frequency range: 1200 to 1600
|
|
Radiochat range: 1441 to 1489 (most devices refuse to be tune to other frequency, even during mapmaking)
|
|
|
|
Radio:
|
|
1459 - standard radio chat
|
|
1351 - Science
|
|
1353 - Command
|
|
1355 - Medical
|
|
1357 - Engineering
|
|
1359 - Security
|
|
1441 - death squad
|
|
1443 - Confession Intercom
|
|
1349 - Miners
|
|
1347 - Cargo techs
|
|
|
|
Devices:
|
|
1451 - tracking implant
|
|
1457 - RSD default
|
|
|
|
On the map:
|
|
1311 for prison shuttle console (in fact, it is not used)
|
|
1435 for status displays
|
|
1437 for atmospherics/fire alerts
|
|
1439 for engine components
|
|
1439 for air pumps, air scrubbers, atmo control
|
|
1441 for atmospherics - supply tanks
|
|
1443 for atmospherics - distribution loop/mixed air tank
|
|
1445 for bot nav beacons
|
|
1447 for mulebot, secbot and ed209 control
|
|
1449 for airlock controls, electropack
|
|
1451 for toxin lab access
|
|
1453 for engineering access
|
|
1455 for AI access
|
|
*/
|
|
|
|
var/list/radiochannels = list(
|
|
"Common" = 1459,
|
|
"Science" = 1351,
|
|
"Command" = 1353,
|
|
"Medical" = 1355,
|
|
"Engineering" = 1357,
|
|
"Security" = 1359,
|
|
"Deathsquad" = 1441,
|
|
"Syndicate" = 1213,
|
|
"Mining" = 1349,
|
|
"Cargo" = 1347,
|
|
)
|
|
//depenging helpers
|
|
var/list/DEPT_FREQS = list(1351,1355,1357,1359,1213,1441,1349,1347)
|
|
var/const/COMM_FREQ = 1353 //command, colored gold in chat window
|
|
var/const/SYND_FREQ = 1213
|
|
|
|
#define TRANSMISSION_WIRE 0
|
|
#define TRANSMISSION_RADIO 1
|
|
|
|
/* filters */
|
|
var/const/RADIO_TO_AIRALARM = "1"
|
|
var/const/RADIO_FROM_AIRALARM = "2"
|
|
var/const/RADIO_CHAT = "3"
|
|
var/const/RADIO_ATMOSIA = "4"
|
|
var/const/RADIO_NAVBEACONS = "5"
|
|
var/const/RADIO_AIRLOCK = "6"
|
|
var/const/RADIO_SECBOT = "7"
|
|
var/const/RADIO_MULEBOT = "8"
|
|
|
|
var/global/datum/controller/radio/radio_controller
|
|
|
|
datum/controller/radio
|
|
var/list/datum/radio_frequency/frequencies = list()
|
|
|
|
proc/add_object(obj/device as obj, var/new_frequency as num, var/filter = null as text|null)
|
|
var/f_text = num2text(new_frequency)
|
|
var/datum/radio_frequency/frequency = frequencies[f_text]
|
|
|
|
if(!frequency)
|
|
frequency = new
|
|
frequency.frequency = new_frequency
|
|
frequencies[f_text] = frequency
|
|
|
|
frequency.add_listener(device, filter)
|
|
return frequency
|
|
|
|
proc/remove_object(obj/device, old_frequency)
|
|
var/f_text = num2text(old_frequency)
|
|
var/datum/radio_frequency/frequency = frequencies[f_text]
|
|
|
|
if(frequency)
|
|
frequency.remove_listener(device)
|
|
|
|
if(frequency.devices.len == 0)
|
|
del(frequency)
|
|
frequencies -= f_text
|
|
|
|
return 1
|
|
|
|
proc/return_frequency(var/frequency as num)
|
|
var/f_text = num2text(frequency)
|
|
return frequencies[f_text]
|
|
|
|
datum/radio_frequency
|
|
var/frequency as num
|
|
var/list/list/obj/devices = list()
|
|
|
|
proc
|
|
post_signal(obj/source as obj|null, datum/signal/signal, var/filter = null as text|null, var/range = null as num|null)
|
|
//log_admin("DEBUG \[[world.timeofday]\]: post_signal {source=\"[source]\", [signal.debug_print()], filter=[filter]}")
|
|
// var/N_f=0
|
|
// var/N_nf=0
|
|
// var/Nt=0
|
|
var/turf/start_point
|
|
if(range)
|
|
start_point = get_turf(source)
|
|
if(!start_point)
|
|
del(signal)
|
|
return 0
|
|
if (filter) //here goes some copypasta. It is for optimisation. -rastaf0
|
|
for(var/obj/device in devices[filter])
|
|
if(device == source)
|
|
continue
|
|
if(range)
|
|
var/turf/end_point = get_turf(device)
|
|
if(!end_point)
|
|
continue
|
|
//if(max(abs(start_point.x-end_point.x), abs(start_point.y-end_point.y)) <= range)
|
|
if(start_point.z!=end_point.z || get_dist(start_point, end_point) > range)
|
|
continue
|
|
device.receive_signal(signal, TRANSMISSION_RADIO, frequency)
|
|
for(var/obj/device in devices["_default"])
|
|
if(device == source)
|
|
continue
|
|
if(range)
|
|
var/turf/end_point = get_turf(device)
|
|
if(!end_point)
|
|
continue
|
|
//if(max(abs(start_point.x-end_point.x), abs(start_point.y-end_point.y)) <= range)
|
|
if(start_point.z!=end_point.z || get_dist(start_point, end_point) > range)
|
|
continue
|
|
device.receive_signal(signal, TRANSMISSION_RADIO, frequency)
|
|
// N_f++
|
|
else
|
|
for (var/next_filter in devices)
|
|
// var/list/obj/DDD = devices[next_filter]
|
|
// Nt+=DDD.len
|
|
for(var/obj/device in devices[next_filter])
|
|
if(device == source)
|
|
continue
|
|
if(range)
|
|
var/turf/end_point = get_turf(device)
|
|
if(!end_point)
|
|
continue
|
|
//if(max(abs(start_point.x-end_point.x), abs(start_point.y-end_point.y)) <= range)
|
|
if(start_point.z!=end_point.z || get_dist(start_point, end_point) > range)
|
|
continue
|
|
device.receive_signal(signal, TRANSMISSION_RADIO, frequency)
|
|
// N_nf++
|
|
|
|
// log_admin("DEBUG: post_signal(source=[source] ([source.x], [source.y], [source.z]),filter=[filter]) frequency=[frequency], N_f=[N_f], N_nf=[N_nf]")
|
|
|
|
|
|
del(signal)
|
|
|
|
add_listener(obj/device as obj, var/filter as text|null)
|
|
if (!filter)
|
|
filter = "_default"
|
|
//log_admin("add_listener(device=[device],filter=[filter]) frequency=[frequency]")
|
|
var/list/obj/devices_line = devices[filter]
|
|
if (!devices_line)
|
|
devices_line = new
|
|
devices[filter] = devices_line
|
|
devices_line+=device
|
|
// var/list/obj/devices_line___ = devices[filter_str]
|
|
// var/l = devices_line___.len
|
|
//log_admin("DEBUG: devices_line.len=[devices_line.len]")
|
|
//log_admin("DEBUG: devices(filter_str).len=[l]")
|
|
|
|
remove_listener(obj/device)
|
|
for (var/devices_filter in devices)
|
|
var/list/devices_line = devices[devices_filter]
|
|
devices_line-=device
|
|
while (null in devices_line)
|
|
devices_line -= null
|
|
if (devices_line.len==0)
|
|
devices -= devices_filter
|
|
del(devices_line)
|
|
|
|
|
|
obj/proc
|
|
receive_signal(datum/signal/signal, receive_method, receive_param)
|
|
return null
|
|
|
|
datum/signal
|
|
var/obj/source
|
|
|
|
var/transmission_method = 0
|
|
//0 = wire
|
|
//1 = radio transmission
|
|
|
|
var/data = list()
|
|
var/encryption
|
|
|
|
proc/copy_from(datum/signal/model)
|
|
source = model.source
|
|
transmission_method = model.transmission_method
|
|
data = model.data
|
|
encryption = model.encryption
|
|
|
|
proc/debug_print()
|
|
if (source)
|
|
. = "signal = {source = '[source]' ([source:x],[source:y],[source:z])\n"
|
|
else
|
|
. = "signal = {source = '[source]' ()\n"
|
|
for (var/i in data)
|
|
. += "data\[\"[i]\"\] = \"[data[i]]\"\n"
|