I am away from any PG database I could test it against, but this (or something very similar) should work just fine for (1):
create or replace function event_ship_date_trigger_func ()
returns opaque as '
begin
if (OLD.reg_state <> ''shipped'' and NEW.reg_state = ''shipped'')
then
new.shipped_date := now();
end if;
return NEW;
end;
' language 'plpgsql';
create or replace trigger event_ship_date_trigger
before insert or update on events_registrations
for each row execute event_ship_date_trigger_func();